Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 103 additions & 11 deletions source/backends/rm86.d
Original file line number Diff line number Diff line change
Expand Up @@ -318,13 +318,44 @@ class BackendRM86 : CompilerBackend {
if (var.offset > 0) {
output ~= format("add di, %d\n", var.offset);
}
output ~= "mov [si], di\n";

if (var.type.isStruct) {
Error(node.error, "Can't push value of struct");
}

if (var.type.size != 2) {
output ~= "xor ax, ax\n";
}

switch (var.type.size) {
case 1: output ~= format("mov al, [di]\n"); break;
case 2: output ~= format("mov ax, [di]\n"); break;
default: Error(node.error, "Bad variable type size");
}

output ~= "mov [si], ax\n";
output ~= "add si, 2\n";
}
else if (node.name in globals) {
auto var = globals[node.name];

output ~= format("mov word [si], __global_%s\n", node.name.Sanitise());
if (var.type.size != 8) {
output ~= "xor ax, ax\n";
}

if (var.type.isStruct) {
Error(node.error, "Can't push value of struct");
}

string symbol = format("__global_%s", node.name.Sanitise());

switch (var.type.size) {
case 1: output ~= format("mov al, [%s]\n", symbol); break;
case 2: output ~= format("mov ax, [%s]\n", symbol); break;
default: Error(node.error, "Bad variable type size");
}

output ~= "mov [si], ax\n";
output ~= "add si, 2\n";
}
else if (node.name in consts) {
Expand Down Expand Up @@ -850,18 +881,37 @@ class BackendRM86 : CompilerBackend {
output ~= "call ax\n";
}

override void CompileFuncAddr(FuncAddrNode node) {
if (node.func !in words) {
Error(node.error, "Function '%s' doesn't exist");
override void CompileAddr(AddrNode node) {
if (node.func in words) {
auto word = words[node.func];
string symbol =
word.raw? node.func : format("__func__%s", node.func.Sanitise());

output ~= format("mov ax, %s\n", symbol);
output ~= "mov [si], ax\n";
output ~= "add si, 2\n";
}
else if (node.func in globals) {
auto var = globals[node.func];

auto word = words[node.func];
string symbol =
word.raw? node.func : format("__func__%s", node.func.Sanitise());
output ~= format(
"mov [si], word __global_%s\n", node.func.Sanitise()
);
output ~= "add si, 2\n";
}
else if (VariableExists(node.func)) {
auto var = GetVariable(node.func);

output ~= format("mov ax, %s\n", symbol);
output ~= "mov [si], ax\n";
output ~= "add si, 2\n";
output ~= "mov di, sp\n";
if (var.offset > 0) {
output ~= format("add di, %d\n", var.offset);
}
output ~= "mov [si], di\n";
output ~= "add si, 2\n";
}
else {
Error(node.error, "Undefined identifier '%s'", node.func);
}
}

override void CompileImplement(ImplementNode node) {
Expand Down Expand Up @@ -927,4 +977,46 @@ class BackendRM86 : CompilerBackend {
inScope = false;
variables = [];
}

override void CompileSet(SetNode node) {
output ~= "sub si, 2\n";
output ~= "mov ax, [si]\n";

if (VariableExists(node.var)) {
auto var = GetVariable(node.var);

if (var.type.isStruct) {
Error(node.error, "Can't set struct value");
}

switch (var.type.size) {
case 1: output ~= format("mov [sp + %d], al\n", var.offset); break;
case 2: output ~= format("mov [sp + %d], ax\n", var.offset); break;
default: Error(node.error, "Bad variable type size");
}
}
else if (node.var in globals) {
auto global = globals[node.var];

if (global.type.isStruct) {
Error(node.error, "Can't set struct value");
}

string symbol = format("__global_%s", node.var.Sanitise());

if (global.type.size != 2) {
output ~= "xor bx, bx\n";
output ~= format("mov [%s], bx\n", symbol);
}

switch (global.type.size) {
case 1: output ~= format("mov [%s], al\n", symbol); break;
case 2: output ~= format("mov [%s], ax\n", symbol); break;
default: Error(node.error, "Bad variable type size");
}
}
else {
Error(node.error, "Variable '%s' doesn't exist", node.var);
}
}
}
100 changes: 92 additions & 8 deletions source/backends/uxn.d
Original file line number Diff line number Diff line change
Expand Up @@ -270,15 +270,36 @@ class BackendUXN : CompilerBackend {
else if (VariableExists(node.name)) {
auto var = GetVariable(node.name);

if (var.type.isStruct) {
Error(node.error, "Can't push value of struct");
}

if (var.offset == 0) {
output ~= ".vsp LDZ2\n";
}
else {
output ~= format(".vsp LDZ2 #%.4x ADD2\n", var.offset);
}

switch (var.type.size) {
case 1: output ~= "LDA NIP\n"; break;
case 2: output ~= "LDA2\n"; break;
default: Error(node.error, "Bad variable type size");
}
}
else if (node.name in globals) {
auto var = globals[node.name];
output ~= format(";global_%s\n", node.name.Sanitise());

if (var.type.isStruct) {
Error(node.error, "Can't push value of struct");
}

switch (var.type.size) {
case 1: output ~= "LDA NIP\n"; break;
case 2: output ~= "LDA2\n"; break;
default: Error(node.error, "Bad variable type size");
}
}
else if (node.name in consts) {
auto value = consts[node.name].value;
Expand Down Expand Up @@ -791,16 +812,30 @@ class BackendUXN : CompilerBackend {
output ~= "JSR2\n";
}

override void CompileFuncAddr(FuncAddrNode node) {
if (node.func !in words) {
Error(node.error, "Function '%s' doesn't exist", node.func);
}
override void CompileAddr(AddrNode node) {
if (node.func in words) {
auto word = words[node.func];
string symbol =
word.raw? node.func : format("func__%s", node.func.Sanitise());

auto word = words[node.func];
string symbol =
word.raw? node.func : format("func__%s", node.func.Sanitise());
output ~= format(";%s\n", symbol);
}
else if (VariableExists(node.func)) {
auto var = GetVariable(node.func);

output ~= format(";%s\n", symbol);
if (var.offset == 0) {
output ~= ".vsp LDZ2\n";
}
else {
output ~= format(".vsp LDZ2 #%.4x ADD2\n", var.offset);
}
}
else if (node.func in globals) {
output ~= format(";global_%s\n", node.func.Sanitise());
}
else {
Error(node.error, "Undefined identifier '%s'", node.func);
}
}

override void CompileImplement(ImplementNode node) {
Expand Down Expand Up @@ -870,4 +905,53 @@ class BackendUXN : CompilerBackend {
inScope = false;
variables = [];
}

override void CompileSet(SetNode node) {
if (VariableExists(node.var)) {
auto var = GetVariable(node.var);

if (var.type.isStruct) {
Error(node.error, "Can't set struct value");
}

if (var.offset == 0) {
switch (var.type.size) {
case 1: output ~= "NIP .vsp LDZ2 STA\n"; break;
case 2: output ~= ".vsp LDZ2 STA2\n"; break;
default: Error(node.error, "Bad variable type size");
}
}
else {
switch (var.type.size) {
case 1: {
output ~= format("NIP .vsp LDZ2 #%.4X ADD2 STA\n", var.offset);
break;
}
case 2: {
output ~= format(".vsp LDZ2 #%.4X ADD2 STA2\n", var.offset);
break;
}
default: Error(node.error, "Bad variable type size");
}
}
}
else if (node.var in globals) {
auto global = globals[node.var];

if (global.type.isStruct) {
Error(node.error, "Can't set struct value");
}

string symbol = format("global_%s", node.var.Sanitise());

switch (global.type.size) {
case 1: output ~= format("NIP ;%s STA\n", symbol); break;
case 2: output ~= format(";%s STA2\n", symbol); break;
default: Error(node.error, "Bad variable type size");
}
}
else {
Error(node.error, "Variable '%s' doesn't exist", node.var);
}
}
}
Loading