@@ -33,6 +33,7 @@ class BackendRM86 : CompilerBackend {
3333 RM86Opts opts;
3434
3535 this () {
36+ addrSize = 2 ;
3637 defaultOS = " dos" ;
3738
3839 types ~= Type(" u8" , 1 );
@@ -217,53 +218,70 @@ class BackendRM86 : CompilerBackend {
217218 output ~= " __stack: times 512 dw 0\n " ;
218219 }
219220
220- void PushVariableValue (Node node, Variable var, size_t size = 0 , size_t offset = 0 , bool member = false ) {
221+ void PushVariableValue (
222+ Node node, Variable var, size_t size = 0 , size_t offset = 0 , bool member = false ,
223+ bool deref = false
224+ ) {
221225 if (size == 0 ) {
222- size = var.type.size;
223- }
224-
225- output ~= " mov di, sp\n " ;
226- if (var.offset > 0 ) {
227- output ~= format(" add di, %d\n " , var.offset + offset);
228- }
229-
230- if (var.type.isStruct && ! member) {
231- Error(node.error, " Can't push value of struct" );
226+ size = var.type.Size();
232227 }
233228
234229 if (size != 2 ) {
235230 output ~= " xor ax, ax\n " ;
236231 }
237232
238- switch (size) {
239- case 1 : output ~= format(" mov al, [di]\n " ); break ;
240- case 2 : output ~= format(" mov ax, [di]\n " ); break ;
241- default : Error (node.error, " Bad variable type size" );
233+ output ~= " mov di, sp\n " ;
234+
235+ if (deref) {
236+ output ~= format(" mov bx, [di + %d]\n " , var.offset);
237+
238+ switch (size) {
239+ case 1 : output ~= format(" mov al, [bx + %d]\n " , offset); break ;
240+ case 2 : output ~= format(" mov ax, [bx + %d]\n " , offset); break ;
241+ default : Error (node.error, " Bad variable type size" );
242+ }
243+ }
244+ else {
245+ switch (size) {
246+ case 1 : output ~= format(" mov al, [di + %d]\n " , var.offset + offset); break ;
247+ case 2 : output ~= format(" mov ax, [di + %d]\n " , var.offset + offset); break ;
248+ default : Error (node.error, " Bad variable type size" );
249+ }
242250 }
243251
244252 output ~= " mov [si], ax\n " ;
245253 output ~= " add si, 2\n " ;
246254 }
247255
248- void PushGlobalValue (Node node, Global var, size_t size = 0 , size_t offset = 0 , bool member = false ) {
256+ void PushGlobalValue (
257+ Node node, Global var, size_t size = 0 , size_t offset = 0 , bool member = false ,
258+ bool deref = false
259+ ) {
249260 if (size == 0 ) {
250- size = var.type.size ;
261+ size = var.type.Size() ;
251262 }
252263
253264 if (size != 2 ) {
254265 output ~= " xor ax, ax\n " ;
255266 }
256267
257- if (var.type.isStruct && ! member) {
258- Error(node.error, " Can't push value of struct" );
259- }
260-
261268 string symbol = format(" __global_%s" , var.name.Sanitise());
262269
263- switch (size) {
264- case 1 : output ~= format(" mov al, [%s + %d]\n " , symbol, offset); break ;
265- case 2 : output ~= format(" mov ax, [%s + %d]\n " , symbol, offset); break ;
266- default : Error (node.error, " Bad variable type size" );
270+ if (deref) {
271+ output ~= format(" mov bx, [%s]\n " , symbol);
272+
273+ switch (size) {
274+ case 1 : output ~= format(" mov al, [bx + %d]\n " , offset); break ;
275+ case 2 : output ~= format(" mov ax, [bx + %d]\n " , offset); break ;
276+ default : Error (node.error, " Bad variable type size" );
277+ }
278+ }
279+ else {
280+ switch (size) {
281+ case 1 : output ~= format(" mov al, [%s + %d]\n " , symbol, offset); break ;
282+ case 2 : output ~= format(" mov ax, [%s + %d]\n " , symbol, offset); break ;
283+ default : Error (node.error, " Bad variable type size" );
284+ }
267285 }
268286
269287 output ~= " mov [si], ax\n " ;
@@ -342,10 +360,18 @@ class BackendRM86 : CompilerBackend {
342360 auto structVar = GetStructVariable(node, node.name);
343361
344362 if (GlobalExists(name)) {
345- PushGlobalValue(node, GetGlobal (name), structVar.size, structVar.offset, true );
363+ auto var = GetGlobal(name);
364+
365+ PushGlobalValue(
366+ node, var, structVar.size, structVar.offset, true , var.type.ptr
367+ );
346368 }
347369 else if (VariableExists(name)) {
348- PushVariableValue(node, GetVariable (name), structVar.size, structVar.offset, true );
370+ auto var = GetVariable(name);
371+
372+ PushVariableValue(
373+ node, var, structVar.size, structVar.offset, true , var.type.ptr
374+ );
349375 }
350376 }
351377 else if (node.name in consts) {
@@ -927,46 +953,59 @@ class BackendRM86 : CompilerBackend {
927953 variables = [];
928954 }
929955
930- void SetVariable (Node node, Variable var, size_t size = 0 , size_t offset = 0 , bool member = false ) {
956+ void SetVariable (
957+ Node node, Variable var, size_t size = 0 , size_t offset = 0 , bool member = false ,
958+ bool deref = false
959+ ) {
931960 if (size == 0 ) {
932- size = var.type.size;
933- }
934-
935- if (var.type.isStruct && ! member) {
936- Error(node.error, " Can't set struct value" );
961+ size = var.type.Size();
937962 }
938963
939- output ~= " mov bx , sp\n " ;
964+ output ~= " mov di , sp\n " ;
940965
941- string addr = var.offset == 0 ? " bx" : format(" bx + %d" , var.offset);
966+ if (deref) {
967+ output ~= format(" mov bx, [di + %d]\n " , var.offset);
942968
943- switch (size) {
944- case 1 : output ~= format(" mov [%s], al\n " , addr); break ;
945- case 2 : output ~= format(" mov [%s], ax\n " , addr); break ;
946- default : Error (node.error, " Bad variable type size" );
969+ switch (size) {
970+ case 1 : output ~= format(" mov [bx + %d], al\n " , offset); break ;
971+ case 2 : output ~= format(" mov [bx + %d], ax\n " , offset); break ;
972+ default : Error (node.error, " Bad variable type size" );
973+ }
974+ }
975+ else {
976+ switch (size) {
977+ case 1 : output ~= format(" mov [di + %d], al\n " , var.offset + offset); break ;
978+ case 2 : output ~= format(" mov [di + %d], ax\n " , var.offset + offset); break ;
979+ default : Error (node.error, " Bad variable type size" );
980+ }
947981 }
948982 }
949983
950- void SetGlobal (Node node, Global global, size_t size = 0 , size_t offset = 0 , bool member = false ) {
984+ void SetGlobal (
985+ Node node, Global global, size_t size = 0 , size_t offset = 0 , bool member = false ,
986+ bool deref = false
987+ ) {
951988 if (size == 0 ) {
952- size = global.type.size;
953- }
954-
955- if (global.type.isStruct && ! member) {
956- Error(node.error, " Can't set struct value" );
989+ size = global.type.Size();
957990 }
958991
959992 string symbol = format(" __global_%s" , global.name.Sanitise());
960993
961- if (size != 2 ) {
962- output ~= " xor bx, bx\n " ;
963- output ~= format(" mov [%s], bx\n " , symbol);
964- }
994+ if (deref) {
995+ output ~= format(" mov bx, [%s]\n " , symbol);
965996
966- switch (size) {
967- case 1 : output ~= format(" mov [%s], al\n " , symbol); break ;
968- case 2 : output ~= format(" mov [%s], ax\n " , symbol); break ;
969- default : Error (node.error, " Bad variable type size" );
997+ switch (size) {
998+ case 1 : output ~= format(" mov [bx + %d], al\n " , offset); break ;
999+ case 2 : output ~= format(" mov [bx + %d], ax\n " , offset); break ;
1000+ default : Error (node.error, " Bad variable type size" );
1001+ }
1002+ }
1003+ else {
1004+ switch (size) {
1005+ case 1 : output ~= format(" mov [%s], al\n " , symbol); break ;
1006+ case 2 : output ~= format(" mov [%s], ax\n " , symbol); break ;
1007+ default : Error (node.error, " Bad variable type size" );
1008+ }
9701009 }
9711010 }
9721011
@@ -975,20 +1014,40 @@ class BackendRM86 : CompilerBackend {
9751014 output ~= " mov ax, [si]\n " ;
9761015
9771016 if (VariableExists(node.var)) {
978- SetVariable(node, GetVariable (node.var));
1017+ auto var = GetVariable(node.var);
1018+
1019+ if (var.type.isStruct && ! var.type.ptr) {
1020+ Error(node.error, " Can't set struct value" );
1021+ }
1022+
1023+ SetVariable(node, var);
9791024 }
9801025 else if (GlobalExists(node.var)) {
1026+ auto var = GetGlobal(node.var);
1027+
1028+ if (var.type.isStruct && ! var.type.ptr) {
1029+ Error(node.error, " Can't set struct value" );
1030+ }
1031+
9811032 SetGlobal(node, GetGlobal (node.var));
9821033 }
9831034 else if (IsStructMember(node.var)) {
9841035 string name = node.var[0 .. node.var.countUntil(" ." )];
9851036 auto structVar = GetStructVariable(node, node.var);
9861037
9871038 if (VariableExists(name)) {
988- SetVariable(node, GetVariable (name), structVar.size, structVar.offset, true );
1039+ auto var = GetVariable(name);
1040+
1041+ SetVariable(
1042+ node, var, structVar.size, structVar.offset, true , var.type.ptr
1043+ );
9891044 }
9901045 else if (GlobalExists(name)) {
991- SetGlobal(node, GetGlobal (name), structVar.size, structVar.offset, true );
1046+ auto var = GetGlobal(name);
1047+
1048+ SetGlobal(
1049+ node, var, structVar.size, structVar.offset, true , var.type.ptr
1050+ );
9921051 }
9931052 }
9941053 else {
0 commit comments