@@ -407,64 +407,77 @@ class BackendX86_64 : CompilerBackend {
407407 }
408408 }
409409
410- void PushGlobalValue (Node node, Global var, size_t size = 0 , size_t offset = 0 , bool member = false ) {
410+ void PushGlobalValue (
411+ Node node, Global var, size_t size = 0 , size_t offset = 0 , bool member = false ,
412+ bool deref = false
413+ ) {
411414 if (size == 0 ) {
412- size = var.type.size ;
415+ size = var.type.Size() ;
413416 }
414417
415418 if (size != 8 ) {
416419 output ~= " xor rax, rax\n " ;
417420 }
418421
419- if (var.type.isStruct && ! member) {
420- Error(node.error, " Can't push value of struct" );
421- }
422-
423422 string symbol = format(" __global_%s" , var.name.Sanitise());
424423
425- switch (size) {
426- case 1 : output ~= format(" mov al, [%s" , symbol); break ;
427- case 2 : output ~= format(" mov ax, [%s" , symbol); break ;
428- case 4 : output ~= format(" mov eax, [%s" , symbol); break ;
429- case 8 : output ~= format(" mov rax, [%s" , symbol); break ;
430- default : Error (node.error, " Bad variable type size" );
431- }
424+ if (deref) {
425+ output ~= format(" mov rbx, [%s]\n " , symbol);
432426
433- if (offset == 0 ) output ~= " ]\n " ;
434- else output ~= format(" + %d]\n " , offset);
427+ switch (size) {
428+ case 1 : output ~= format(" mov al, [rbx + %d]\n " , offset); break ;
429+ case 2 : output ~= format(" mov ax, [rbx + %d]\n " , offset); break ;
430+ case 4 : output ~= format(" mov eax, [rbx + %d]\n " , offset); break ;
431+ case 8 : output ~= format(" mov rax, [rbx + %d]\n " , offset); break ;
432+ default : Error (node.error, " Bad variable type size" );
433+ }
434+ }
435+ else {
436+ switch (size) {
437+ case 1 : output ~= format(" mov al, [%s + %d]\n " , symbol, offset); break ;
438+ case 2 : output ~= format(" mov ax, [%s + %d]\n " , symbol, offset); break ;
439+ case 4 : output ~= format(" mov eax, [%s + %d]\n " , symbol, offset); break ;
440+ case 8 : output ~= format(" mov rax, [%s + %d]\n " , symbol, offset); break ;
441+ default : Error (node.error, " Bad variable type size" );
442+ }
443+ }
435444
436445 output ~= " mov [r15], rax\n " ;
437446 output ~= " add r15, 8\n " ;
438447 }
439448
440- void PushVariableValue (Node node, Variable var, size_t size = 0 , size_t offset = 0 , bool member = false ) {
449+ void PushVariableValue (
450+ Node node, Variable var, size_t size = 0 , size_t offset = 0 , bool member = false ,
451+ bool deref = false
452+ ) {
441453 if (size == 0 ) {
442- size = var.type.size;
443- }
444-
445- output ~= " mov rdi, rsp\n " ;
446- if (var.offset > 0 ) {
447- output ~= format(" add rdi, %d\n " , var.offset);
448- }
449-
450- if (var.type.isStruct && ! member) {
451- Error(node.error, " Can't push value of struct" );
454+ size = var.type.Size();
452455 }
453456
454457 if (size != 8 ) {
455458 output ~= " xor rax, rax\n " ;
456459 }
457460
458- switch (size) {
459- case 1 : output ~= format(" mov al, [rdi" ); break ;
460- case 2 : output ~= format(" mov ax, [rdi" ); break ;
461- case 4 : output ~= format(" mov eax, [rdi" ); break ;
462- case 8 : output ~= format(" mov rax, [rdi" ); break ;
463- default : Error (node.error, " Bad variable type size" );
464- }
461+ if (deref) {
462+ output ~= format(" mov rbx, [rsp + %d]\n " , var.offset);
465463
466- if (offset == 0 ) output ~= " ]\n " ;
467- else output ~= format(" + %d]\n " , offset);
464+ switch (size) {
465+ case 1 : output ~= format(" mov al, [rbx + %d]\n " , offset); break ;
466+ case 2 : output ~= format(" mov ax, [rbx + %d]\n " , offset); break ;
467+ case 4 : output ~= format(" mov eax, [rbx + %d]\n " , offset); break ;
468+ case 8 : output ~= format(" mov rax, [rbx + %d]\n " , offset); break ;
469+ default : Error (node.error, " Bad variable type size" );
470+ }
471+ }
472+ else {
473+ switch (size) {
474+ case 1 : output ~= format(" mov al, [rsp + %d]\n " , offset + var.offset); break ;
475+ case 2 : output ~= format(" mov ax, [rsp + %d]\n " , offset + var.offset); break ;
476+ case 4 : output ~= format(" mov eax, [rsp + %d]\n " , offset + var.offset); break ;
477+ case 8 : output ~= format(" mov rax, [rsp + %d]\n " , offset + var.offset); break ;
478+ default : Error (node.error, " Bad variable type size" );
479+ }
480+ }
468481
469482 output ~= " mov [r15], rax\n " ;
470483 output ~= " add r15, 8\n " ;
@@ -609,10 +622,18 @@ class BackendX86_64 : CompilerBackend {
609622 auto structVar = GetStructVariable(node, node.name);
610623
611624 if (GlobalExists(name)) {
612- PushGlobalValue(node, GetGlobal (name), structVar.size, structVar.offset, true );
625+ auto var = GetGlobal(name);
626+
627+ PushGlobalValue(
628+ node, var, structVar.size, structVar.offset, true , var.type.ptr
629+ );
613630 }
614631 else if (VariableExists(name)) {
615- PushVariableValue(node, GetVariable (name), structVar.size, structVar.offset, true );
632+ auto var = GetVariable(name);
633+
634+ PushVariableValue(
635+ node, var, structVar.size, structVar.offset, true , var.type.ptr
636+ );
616637 }
617638 }
618639 else if (node.name in consts) {
@@ -1247,74 +1268,110 @@ class BackendX86_64 : CompilerBackend {
12471268 variables = [];
12481269 }
12491270
1250- void SetVariable (Node node, Variable var, size_t size = 0 , size_t offset = 0 , bool member = false ) {
1271+ void SetVariable (
1272+ Node node, Variable var, size_t size = 0 , size_t offset = 0 , bool member = false ,
1273+ bool deref = false
1274+ ) {
12511275 if (size == 0 ) {
1252- size = var.type.size ;
1276+ size = var.type.Size() ;
12531277 }
12541278
12551279 output ~= " sub r15, 8\n " ;
12561280 output ~= " mov rax, [r15]\n " ;
12571281
1258- if (var.type.isStruct && ! member) {
1259- Error(node.error, " Can't set struct value" );
1260- }
1282+ if (deref) {
1283+ output ~= format(" mov rbx, [rsp + %d]\n " , var.offset);
12611284
1262- switch (size) {
1263- case 1 : output ~= format(" mov [rsp + %d], al\n " , var.offset + offset); break ;
1264- case 2 : output ~= format(" mov [rsp + %d], ax\n " , var.offset + offset); break ;
1265- case 4 : output ~= format(" mov [rsp + %d], eax\n " , var.offset + offset); break ;
1266- case 8 : output ~= format(" mov [rsp + %d], rax\n " , var.offset + offset); break ;
1267- default : Error (node.error, " Bad variable type size" );
1285+ switch (size) {
1286+ case 1 : output ~= format(" mov [rbx + %d], al\n " , offset); break ;
1287+ case 2 : output ~= format(" mov [rbx + %d], ax\n " , offset); break ;
1288+ case 4 : output ~= format(" mov [rbx + %d], eax\n " , offset); break ;
1289+ case 8 : output ~= format(" mov [rbx + %d], rax\n " , offset); break ;
1290+ default : Error (node.error, " Bad variable type size" );
1291+ }
1292+ }
1293+ else {
1294+ switch (size) {
1295+ case 1 : output ~= format(" mov [rsp + %d], al\n " , var.offset + offset); break ;
1296+ case 2 : output ~= format(" mov [rsp + %d], ax\n " , var.offset + offset); break ;
1297+ case 4 : output ~= format(" mov [rsp + %d], eax\n " , var.offset + offset); break ;
1298+ case 8 : output ~= format(" mov [rsp + %d], rax\n " , var.offset + offset); break ;
1299+ default : Error (node.error, " Bad variable type size" );
1300+ }
12681301 }
12691302 }
12701303
12711304 void SetGlobal (
12721305 Node node, Global global, size_t size = 0 , size_t offset = 0 ,
1273- bool member = false
1306+ bool member = false , bool deref = false
12741307 ) {
12751308 if (size == 0 ) {
1276- size = global.type.size ;
1309+ size = global.type.Size() ;
12771310 }
12781311
12791312 output ~= " sub r15, 8\n " ;
12801313 output ~= " mov rax, [r15]\n " ;
12811314
1282- if (global.type.isStruct && ! member) {
1283- Error(node.error, " Can't set struct value" );
1284- }
1285-
12861315 string symbol = format(" __global_%s" , global.name.Sanitise());
12871316
1288- if (size != 8 ) {
1289- output ~= " xor rbx, rbx\n " ;
1290- output ~= format(" mov [%s + %d], rbx\n " , symbol, offset);
1291- }
1317+ if (deref) {
1318+ output ~= format(" mov rbx, [%s]\n " , symbol);
12921319
1293- switch (size) {
1294- case 1 : output ~= format(" mov [%s + %d], al\n " , symbol, offset); break ;
1295- case 2 : output ~= format(" mov [%s + %d], ax\n " , symbol, offset); break ;
1296- case 4 : output ~= format(" mov [%s + %d], eax\n " , symbol, offset); break ;
1297- case 8 : output ~= format(" mov [%s + %d], rax\n " , symbol, offset); break ;
1298- default : Error (node.error, " Bad variable type size" );
1320+ switch (size) {
1321+ case 1 : output ~= format(" mov [rbx + %d], al\n " , offset); break ;
1322+ case 2 : output ~= format(" mov [rbx + %d], ax\n " , offset); break ;
1323+ case 4 : output ~= format(" mov [rbx + %d], eax\n " , offset); break ;
1324+ case 8 : output ~= format(" mov [rbx + %d], rax\n " , offset); break ;
1325+ default : Error (node.error, " Bad variable type size" );
1326+ }
1327+ }
1328+ else {
1329+ switch (size) {
1330+ case 1 : output ~= format(" mov [%s + %d], al\n " , symbol, offset); break ;
1331+ case 2 : output ~= format(" mov [%s + %d], ax\n " , symbol, offset); break ;
1332+ case 4 : output ~= format(" mov [%s + %d], eax\n " , symbol, offset); break ;
1333+ case 8 : output ~= format(" mov [%s + %d], rax\n " , symbol, offset); break ;
1334+ default : Error (node.error, " Bad variable type size" );
1335+ }
12991336 }
13001337 }
13011338
13021339 override void CompileSet (SetNode node) {
13031340 if (VariableExists(node.var)) {
1304- SetVariable(node, GetVariable (node.var));
1341+ auto var = GetVariable(node.var);
1342+
1343+ if (var.type.isStruct && ! var.type.ptr) {
1344+ Error(node.error, " Can't set struct value" );
1345+ }
1346+
1347+ SetVariable(node, var);
13051348 }
13061349 else if (GlobalExists(node.var)) {
1350+ auto var = GetGlobal(node.var);
1351+
1352+ if (var.type.isStruct && ! var.type.ptr) {
1353+ Error(node.error, " Can't set struct value" );
1354+ }
1355+
13071356 SetGlobal(node, GetGlobal (node.var));
13081357 }
13091358 else if (IsStructMember(node.var)) {
13101359 string name = node.var[0 .. node.var.countUntil(" ." )];
13111360 auto structVar = GetStructVariable(node, node.var);
13121361
13131362 if (VariableExists(name)) {
1314- SetVariable(node, GetVariable (name), structVar.size, structVar.offset, true );
1363+ auto var = GetVariable(name);
1364+
1365+ SetVariable(
1366+ node, var, structVar.size, structVar.offset, true , var.type.ptr
1367+ );
13151368 }
13161369 else if (GlobalExists(name)) {
1317- SetGlobal(node, GetGlobal (name), structVar.size, structVar.offset, true );
1370+ auto var = GetGlobal(name);
1371+
1372+ SetGlobal(
1373+ node, var, structVar.size, structVar.offset, true , var.type.ptr
1374+ );
13181375 }
13191376 }
13201377 else {
0 commit comments