Skip to content

Commit a62445b

Browse files
committed
uxn
1 parent 0cbeba8 commit a62445b

File tree

1 file changed

+109
-48
lines changed

1 file changed

+109
-48
lines changed

source/backends/uxn.d

Lines changed: 109 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class BackendUXN : CompilerBackend {
2828
uint currentLoop;
2929

3030
this() {
31+
addrSize = 2;
32+
3133
types ~= Type("u8", 1);
3234
types ~= Type("i8", 1);
3335
types ~= Type("u16", 2);
@@ -182,43 +184,62 @@ class BackendUXN : CompilerBackend {
182184
}
183185

184186
void PushVariableValue(
185-
Node node, Variable var, size_t size = 0, size_t offset = 0, bool member = false
187+
Node node, Variable var, size_t size = 0, size_t offset = 0, bool member = false,
188+
bool deref = false
186189
) {
187190
if (size == 0) {
188-
size = var.type.size;
189-
}
190-
if (var.type.isStruct && !member) {
191-
Error(node.error, "Can't push value of struct");
191+
size = var.type.Size();
192192
}
193193

194-
if (var.offset == 0) {
195-
output ~= ".vsp LDZ2\n";
194+
if (deref) {
195+
if (var.offset == 0) {
196+
output ~= ".vsp LDZ2\n";
197+
}
198+
else {
199+
output ~= format(".vsp LDZ2 #%.4x ADD2\n", var.offset);
200+
}
201+
202+
output ~= "LDA2\n";
203+
204+
if (offset != 0) {
205+
output ~= format("#%.4x ADD2\n", offset);
206+
}
196207
}
197208
else {
198-
output ~= format(".vsp LDZ2 #%.4x ADD2\n", var.offset);
209+
if (var.offset + offset == 0) {
210+
output ~= ".vsp LDZ2\n";
211+
}
212+
else {
213+
output ~= format(".vsp LDZ2 #%.4x ADD2\n", var.offset + offset);
214+
}
199215
}
200216

201-
switch (var.type.size) {
217+
switch (size) {
202218
case 1: output ~= "LDA NIP\n"; break;
203219
case 2: output ~= "LDA2\n"; break;
204220
default: Error(node.error, "Bad variable type size");
205221
}
206222
}
207223

208224
void PushGlobalValue(
209-
Node node, Global var, size_t size = 0, size_t offset = 0, bool member = false
225+
Node node, Global var, size_t size = 0, size_t offset = 0, bool member = false,
226+
bool deref = false
210227
) {
211228
if (size == 0) {
212-
size = var.type.size;
229+
size = var.type.Size();
213230
}
214231

215232
output ~= format(";global_%s\n", var.name.Sanitise());
216233

217-
if (var.type.isStruct && !member) {
218-
Error(node.error, "Can't push value of struct");
234+
if (deref) {
235+
output ~= "LDA2\n";
236+
}
237+
238+
if (offset != 0) {
239+
output ~= format("#%.4x ADD2\n", offset);
219240
}
220241

221-
switch (var.type.size) {
242+
switch (size) {
222243
case 1: output ~= "LDA NIP\n"; break;
223244
case 2: output ~= "LDA2\n"; break;
224245
default: Error(node.error, "Bad variable type size");
@@ -287,20 +308,40 @@ class BackendUXN : CompilerBackend {
287308
}
288309
}
289310
else if (VariableExists(node.name)) {
311+
auto var = GetVariable(node.name);
312+
313+
if (var.type.isStruct && !var.type.ptr) {
314+
Error(node.error, "Can't push value of structures");
315+
}
316+
290317
PushVariableValue(node, GetVariable(node.name));
291318
}
292319
else if (GlobalExists(node.name)) {
320+
auto var = GetGlobal(node.name);
321+
322+
if (var.type.isStruct && !var.type.ptr) {
323+
Error(node.error, "Can't push value of structures");
324+
}
325+
293326
PushGlobalValue(node, GetGlobal(node.name));
294327
}
295328
else if (IsStructMember(node.name)) {
296329
string name = node.name[0 .. node.name.countUntil(".")];
297330
auto structVar = GetStructVariable(node, node.name);
298331

299332
if (GlobalExists(name)) {
300-
PushGlobalValue(node, GetGlobal(name), structVar.size, structVar.offset, true);
333+
auto var = GetGlobal(name);
334+
335+
PushGlobalValue(
336+
node, var, structVar.size, structVar.offset, true, var.type.ptr
337+
);
301338
}
302339
else if (VariableExists(name)) {
303-
PushVariableValue(node, GetVariable(name), structVar.size, structVar.offset, true);
340+
auto var = GetVariable(name);
341+
342+
PushVariableValue(
343+
node, var, structVar.size, structVar.offset, true, var.type.ptr
344+
);
304345
}
305346
}
306347
else if (node.name in consts) {
@@ -852,50 +893,50 @@ class BackendUXN : CompilerBackend {
852893
}
853894

854895
void SetVariable(
855-
Node node, Variable var, size_t size = 0, size_t offset = 0, bool member = false
896+
Node node, Variable var, size_t size = 0, size_t offset = 0, bool member = false,
897+
bool deref = false
856898
) {
857899
if (size == 0) {
858-
size = var.type.size;
859-
}
860-
if (var.type.isStruct && !member) {
861-
Error(node.error, "Can't set struct value");
900+
size = var.type.Size();
862901
}
863902

864-
if (var.offset == 0) {
865-
switch (var.type.size) {
866-
case 1: output ~= "NIP .vsp LDZ2 STA\n"; break;
867-
case 2: output ~= ".vsp LDZ2 STA2\n"; break;
868-
default: Error(node.error, "Bad variable type size");
869-
}
903+
string where = ".vsp LDZ2";
904+
905+
if (var.offset != 0) {
906+
where ~= format(" #%.4x ADD2", var.offset);
870907
}
871-
else {
872-
switch (var.type.size) {
873-
case 1: {
874-
output ~= format("NIP .vsp LDZ2 #%.4X ADD2 STA\n", var.offset);
875-
break;
876-
}
877-
case 2: {
878-
output ~= format(".vsp LDZ2 #%.4X ADD2 STA2\n", var.offset);
879-
break;
880-
}
881-
default: Error(node.error, "Bad variable type size");
882-
}
908+
if (deref) {
909+
where ~= " LDA2";
910+
}
911+
if (offset != 0) {
912+
where ~= format(" #%.4x ADD2", offset);
913+
}
914+
915+
switch (size) {
916+
case 1: output ~= format("NIP %s STA\n", where); break;
917+
case 2: output ~= format("%s STA2\n", where); break;
918+
default: Error(node.error, "Bad variable type size");
883919
}
884920
}
885921

886922
void SetGlobal(
887-
Node node, Global global, size_t size = 0, size_t offset = 0, bool member = false
923+
Node node, Global global, size_t size = 0, size_t offset = 0, bool member = false,
924+
bool deref = false
888925
) {
889926
if (size == 0) {
890-
size = global.type.size;
891-
}
892-
if (global.type.isStruct && !member) {
893-
Error(node.error, "Can't set struct value");
927+
size = global.type.Size();
894928
}
895929

896930
string symbol = format("global_%s", global.name.Sanitise());
897931

898-
switch (global.type.size) {
932+
if (deref) {
933+
symbol ~= format(" LDA2");
934+
}
935+
if (offset != 0) {
936+
symbol ~= format(" #%.4x ADD2", offset);
937+
}
938+
939+
switch (size) {
899940
case 1: output ~= format("NIP ;%s STA\n", symbol); break;
900941
case 2: output ~= format(";%s STA2\n", symbol); break;
901942
default: Error(node.error, "Bad variable type size");
@@ -904,20 +945,40 @@ class BackendUXN : CompilerBackend {
904945

905946
override void CompileSet(SetNode node) {
906947
if (VariableExists(node.var)) {
907-
SetVariable(node, GetVariable(node.var));
948+
auto var = GetVariable(node.var);
949+
950+
if (var.type.isStruct && !var.type.ptr) {
951+
Error(node.error, "Can't set struct value");
952+
}
953+
954+
SetVariable(node, var);
908955
}
909956
else if (GlobalExists(node.var)) {
957+
auto var = GetGlobal(node.var);
958+
959+
if (var.type.isStruct && !var.type.ptr) {
960+
Error(node.error, "Can't set struct value");
961+
}
962+
910963
SetGlobal(node, GetGlobal(node.var));
911964
}
912965
else if (IsStructMember(node.var)) {
913966
string name = node.var[0 .. node.var.countUntil(".")];
914967
auto structVar = GetStructVariable(node, node.var);
915968

916969
if (VariableExists(name)) {
917-
SetVariable(node, GetVariable(name), structVar.size, structVar.offset, true);
970+
auto var = GetVariable(name);
971+
972+
SetVariable(
973+
node, var, structVar.size, structVar.offset, true, var.type.ptr
974+
);
918975
}
919976
else if (GlobalExists(name)) {
920-
SetGlobal(node, GetGlobal(name), structVar.size, structVar.offset, true);
977+
auto var = GetGlobal(name);
978+
979+
SetGlobal(
980+
node, var, structVar.size, structVar.offset, true, var.type.ptr
981+
);
921982
}
922983
}
923984
else {

0 commit comments

Comments
 (0)