Skip to content

Commit a3d9bfe

Browse files
committed
rm86
1 parent 5cf3784 commit a3d9bfe

File tree

1 file changed

+115
-56
lines changed

1 file changed

+115
-56
lines changed

source/backends/rm86.d

Lines changed: 115 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)