Skip to content

Commit e04b033

Browse files
committed
broken uxn backend
1 parent d061cc8 commit e04b033

File tree

4 files changed

+129
-18
lines changed

4 files changed

+129
-18
lines changed

examples/exceptions.cal

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,13 @@
11
include "cores/select.cal"
22
include "std/io.cal"
33

4-
func __lua_exception begin
5-
&_cal_exception Exception.msg + "Unhandled exception: %s" printf new_line
4+
func __uxn_exception begin
5+
65 printch new_line
66
1 exit
77
end
88

9-
func exception_msg begin
10-
&_cal_exception Exception.msg +
11-
end
12-
139
func error foo begin
1410
c"hi im an exception" throw
1511
end
1612

17-
try foo
18-
catch
19-
exception_msg printstr new_line
20-
end
21-
2213
foo

source/backends/uxn.d

Lines changed: 118 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ private struct Word {
1515
bool raw;
1616
bool inline;
1717
Node[] inlineNodes;
18+
bool error;
1819
}
1920

2021
private struct StructEntry {
@@ -85,6 +86,7 @@ class BackendUXN : CompilerBackend {
8586
types ~= Type("size", 2);
8687
types ~= Type("usize", 2);
8788
types ~= Type("cell", 2);
89+
types ~= Type("bool", 2);
8890

8991
// built in structs
9092
types ~= Type("Array", 6, true, [
@@ -108,13 +110,15 @@ class BackendUXN : CompilerBackend {
108110
foreach (ref type ; types) {
109111
NewConst(format("%s.sizeof", type.name), cast(long) type.size);
110112
}
113+
114+
globals["_cal_exception"] = Global(GetType("Exception"), false, 0);
111115
}
112116

113117
override string[] GetVersions() => [
114118
// platform
115119
"UXN", "BigEndian", "16Bit",
116120
// features
117-
"IO"
121+
"IO", "Exit"
118122
];
119123

120124
override string[] FinalCommands() => [
@@ -281,6 +285,31 @@ class BackendUXN : CompilerBackend {
281285
output ~= format("func__%s\n", node.name.Sanitise());
282286
}
283287
}
288+
289+
if (word.error) {
290+
if ("__uxn_exception" in words) {
291+
bool crash;
292+
293+
if (inScope) {
294+
crash = !words[thisFunc].error;
295+
}
296+
else {
297+
crash = true;
298+
}
299+
300+
if (crash) {
301+
output ~= format(";global_%s LDA2\n", Sanitise("_cal_exception"));
302+
output ~= "#0000 NEQ2\n";
303+
output ~= format(";func__%s JCN\n", Sanitise("__uxn_exception"));
304+
}
305+
else {
306+
CompileReturn(node);
307+
}
308+
}
309+
else {
310+
Warn(node.error, "No exception handler");
311+
}
312+
}
284313
}
285314
else if (VariableExists(node.name)) {
286315
auto var = GetVariable(node.name);
@@ -346,19 +375,27 @@ class BackendUXN : CompilerBackend {
346375
thisFunc = node.name;
347376

348377
if (node.inline) {
349-
words[node.name] = Word(false, true, node.nodes);
378+
if (node.errors) {
379+
output ~= format("#0000 ;global_%s STA2\n", Sanitise("_cal_exception"));
380+
}
381+
382+
words[node.name] = Word(false, true, node.nodes, node.errors);
350383
}
351384
else {
352385
assert(!inScope);
353386
inScope = true;
354387

355-
words[node.name] = Word(node.raw, false, []);
388+
words[node.name] = Word(node.raw, false, [], node.errors);
356389

357390
string symbol =
358391
node.raw? node.name : format("func__%s", node.name.Sanitise());
359392

360393
output ~= format("@%s\n", symbol);
361394

395+
if (node.errors) {
396+
output ~= format("#0000 ;global_%s STA2\n", Sanitise("_cal_exception"));
397+
}
398+
362399
// allocate parameters
363400
size_t paramSize = node.params.length * 2;
364401
foreach (ref type ; node.paramTypes) {
@@ -1001,6 +1038,82 @@ class BackendUXN : CompilerBackend {
10011038
}
10021039
}
10031040

1004-
override void CompileTryCatch(TryCatchNode node) {}
1005-
override void CompileThrow(WordNode node) {}
1041+
override void CompileTryCatch(TryCatchNode node) {
1042+
if (node.func !in words) {
1043+
Error(node.error, "Function '%s' doesn't exist", node.func);
1044+
}
1045+
1046+
auto word = words[node.func];
1047+
1048+
if (!word.error) {
1049+
Error(node.error, "Function '%s' doesn't throw", node.func);
1050+
}
1051+
if (word.raw) {
1052+
Error(node.error, "Non-callisto functions can't throw");
1053+
}
1054+
1055+
if (word.inline) {
1056+
foreach (inode ; word.inlineNodes) {
1057+
compiler.CompileNode(inode);
1058+
}
1059+
}
1060+
else {
1061+
output ~= format("func__%s\n", node.func.Sanitise());
1062+
}
1063+
1064+
++ blockCounter;
1065+
1066+
output ~= format(";global_%s LDA2 #0000 EQU\n", Sanitise("_cal_exception"));
1067+
output ~= format(";catch_%d_end JCN\n", blockCounter);
1068+
1069+
// create scope
1070+
auto oldVars = variables.dup;
1071+
auto oldSize = GetStackSize();
1072+
1073+
foreach (inode ; node.catchBlock) {
1074+
compiler.CompileNode(inode);
1075+
}
1076+
1077+
// remove scope
1078+
foreach (ref var ; variables) {
1079+
if (oldVars.canFind(var)) continue;
1080+
if (!var.type.hasDeinit) continue;
1081+
1082+
output ~= format(".vsp LDZ2 #.2x ADD2", var.offset);
1083+
output ~= format("type_deinit_%s\n", Sanitise(var.type.name));
1084+
}
1085+
if (GetStackSize() - oldSize > 0) {
1086+
output ~= format(
1087+
".vsp LDZ2 #%.4x ADD .vsp STZ2\n", GetStackSize() - oldSize
1088+
);
1089+
}
1090+
variables = oldVars;
1091+
1092+
output ~= format("@catch_%d_end\n", blockCounter);
1093+
}
1094+
1095+
override void CompileThrow(WordNode node) {
1096+
if (!inScope || (!words[thisFunc].error)) {
1097+
Error(node.error, "Not in a function that can throw");
1098+
}
1099+
if (words[thisFunc].inline) {
1100+
Error(node.error, "Can't use throw in an inline function");
1101+
}
1102+
1103+
// set exception error
1104+
output ~= format("#ffff ;global_%s STA2\n", Sanitise("_cal_exception"));
1105+
1106+
// copy exception message
1107+
// TODO: make this less bloat
1108+
foreach (i ; 0 .. 3) {
1109+
output ~= "DUP2 LDA2\n";
1110+
output ~= format(
1111+
";global_%s #%.2x ADD2 STA2\n", Sanitise("_cal_exception"), i + 1
1112+
);
1113+
output ~= "#0002 ADD2\n";
1114+
}
1115+
output ~= "POP2\n";
1116+
1117+
CompileReturn(node);
1118+
}
10061119
}

source/codeRemover.d

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,15 @@ class CodeRemover {
1919
"__x86_64_program_exit",
2020
"__rm86_program_init",
2121
"__rm86_program_exit",
22+
"__arm64_program_init",
23+
"__arm64_program_exit",
2224
"uxn_program_init",
23-
"uxn_program_end"
25+
"uxn_program_end",
26+
"__x86_64_exception",
27+
"__rm86_exception",
28+
"__uxn_exception",
29+
"__arm64_exception",
30+
"__lua_exception",
2431
];
2532
}
2633

std

Submodule std updated 1 file

0 commit comments

Comments
 (0)