Skip to content

Commit ea47332

Browse files
committed
fix constructors
1 parent fc9e089 commit ea47332

File tree

5 files changed

+157
-25
lines changed

5 files changed

+157
-25
lines changed

examples/initDeinit.cal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ implement meow deinit
1515
end
1616

1717
let meow myMeow
18-
myMeow @ printdec new_line
18+
&myMeow @ printdec new_line

source/backends/lua.d

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,13 @@ class BackendLua : CompilerBackend {
206206
}
207207

208208
override void End() {
209+
// call destructors
210+
foreach (name, global ; globals) {
211+
output ~= format("mem[dsp] = %d\n", global.addr);
212+
output ~= "dsp = dsp + 1\n";
213+
output ~= format("type_deinit_%s()\n", global.type.name.Sanitise());
214+
}
215+
209216
output ~= "end\n";
210217

211218
// create arrays
@@ -326,6 +333,12 @@ class BackendLua : CompilerBackend {
326333
size_t scopeSize;
327334
foreach (ref var ; variables) {
328335
scopeSize += var.Size();
336+
337+
if (var.type.hasDeinit) {
338+
output ~= format("mem[dsp] = vsp + %d\n", var.offset);
339+
output ~= "dsp = dsp + 1\n";
340+
output ~= format("type_deinit_%s()\n", var.type.name.Sanitise());
341+
}
329342
}
330343
output ~= format("vsp = vsp + %d\n", scopeSize);
331344
output ~= "end\n";
@@ -358,6 +371,14 @@ class BackendLua : CompilerBackend {
358371
}
359372

360373
// remove scope
374+
foreach (ref var ; variables) {
375+
if (oldVars.canFind(var)) continue;
376+
if (!var.type.hasDeinit) continue;
377+
378+
output ~= format("mem[dsp] = vsp + %d\n", var.offset);
379+
output ~= "dsp = dsp + 1\n";
380+
output ~= format("type_deinit_%s()\n", var.type.name.Sanitise());
381+
}
361382
if (GetStackSize() - oldSize > 0) {
362383
output ~= format("vsp = vsp + %d\n", GetStackSize() - oldSize);
363384
}
@@ -370,9 +391,27 @@ class BackendLua : CompilerBackend {
370391
}
371392

372393
if (node.hasElse) {
394+
// create scope
395+
auto oldVars = variables.dup;
396+
auto oldSize = GetStackSize();
397+
373398
foreach (ref inode ; node.doElse) {
374399
compiler.CompileNode(inode);
375400
}
401+
402+
// remove scope
403+
foreach (ref var ; variables) {
404+
if (oldVars.canFind(var)) continue;
405+
if (!var.type.hasDeinit) continue;
406+
407+
output ~= format("mem[dsp] = vsp + %d\n", var.offset);
408+
output ~= "dsp = dsp + 1\n";
409+
output ~= format("type_deinit_%s()\n", var.type.name.Sanitise());
410+
}
411+
if (GetStackSize() - oldSize > 0) {
412+
output ~= format("vsp = vsp + %d\n", GetStackSize() - oldSize);
413+
}
414+
variables = oldVars;
376415
}
377416

378417
output ~= format("::if_%d_end::\n", blockNum);
@@ -399,6 +438,14 @@ class BackendLua : CompilerBackend {
399438

400439
// restore scope
401440
output ~= format("::while_%d_next::\n", blockNum);
441+
foreach (ref var ; variables) {
442+
if (oldVars.canFind(var)) continue;
443+
if (!var.type.hasDeinit) continue;
444+
445+
output ~= format("mem[dsp] = vsp + %d\n", var.offset);
446+
output ~= "dsp = dsp + 1\n";
447+
output ~= format("type_deinit_%s()\n", var.type.name.Sanitise());
448+
}
402449
if (GetStackSize() - oldSize > 0) {
403450
output ~= format("vsp = vsp + %d\n", GetStackSize() - oldSize);
404451
}
@@ -447,6 +494,12 @@ class BackendLua : CompilerBackend {
447494
if (var.Size() == 1) {
448495
output ~= "mem[vsp] = 0\n";
449496
}
497+
498+
if (var.type.hasInit) { // call constructor
499+
output ~= "mem[dsp] = vsp\n";
500+
output ~= "dsp = dsp + 1\n";
501+
output ~= format("type_init_%s()\n", var.type.name.Sanitise());
502+
}
450503
}
451504
else {
452505
Global global;
@@ -458,6 +511,12 @@ class BackendLua : CompilerBackend {
458511
globals ~= global;
459512

460513
globalStack += global.Size();
514+
515+
if (global.type.hasInit) { // call constructor
516+
output ~= format("mem[dsp] = %d\n", global.addr);
517+
output ~= "dsp = dsp + 1\n";
518+
output ~= format("type_init_%s()\n", global.type.name.Sanitise());
519+
}
461520
}
462521
}
463522

@@ -622,6 +681,12 @@ class BackendLua : CompilerBackend {
622681
size_t scopeSize;
623682
foreach (ref var ; variables) {
624683
scopeSize += var.Size();
684+
685+
if (var.type.hasDeinit) {
686+
output ~= format("mem[dsp] = vsp + %d\n", var.offset);
687+
output ~= "dsp = dsp + 1\n";
688+
output ~= format("type_deinit_%s()\n", var.type.name.Sanitise());
689+
}
625690
}
626691
output ~= format("vsp = vsp + %d\n", scopeSize);
627692

@@ -754,7 +819,64 @@ class BackendLua : CompilerBackend {
754819
output ~= "dsp = dsp + 1\n";
755820
}
756821

757-
override void CompileImplement(ImplementNode node) {}
822+
override void CompileImplement(ImplementNode node) {
823+
if (!TypeExists(node.structure)) {
824+
Error(node.error, "Type '%s' doesn't exist", node.structure);
825+
}
826+
auto type = GetType(node.structure);
827+
828+
string labelName;
829+
830+
switch (node.method) {
831+
case "init": {
832+
if (GetType(node.structure).hasInit) {
833+
Error(node.error, "Already implemented in type");
834+
}
835+
836+
type.hasInit = true;
837+
labelName = format("type_init_%s", Sanitise(node.structure));
838+
break;
839+
}
840+
case "deinit": {
841+
if (GetType(node.structure).hasDeinit) {
842+
Error(node.error, "Already implemented in type");
843+
}
844+
845+
type.hasDeinit = true;
846+
labelName = format("type_deinit_%s", Sanitise(node.structure));
847+
break;
848+
}
849+
default: Error(node.error, "Unknown method '%s'", node.method);
850+
}
851+
852+
SetType(type.name, type);
853+
854+
assert(!inScope);
855+
inScope = true;
856+
857+
output ~= format("function %s()\n", labelName);
858+
859+
foreach (ref inode ; node.nodes) {
860+
compiler.CompileNode(inode);
861+
}
862+
863+
size_t scopeSize;
864+
foreach (ref var ; variables) {
865+
scopeSize += var.Size();
866+
867+
if (var.type.hasDeinit) {
868+
output ~= format("lea rax, [rsp + %d\n]", var.offset);
869+
output ~= "mov [r15], rax\n";
870+
output ~= "add r15, 8\n";
871+
output ~= format("call __type_deinit_%s\n", Sanitise(var.type.name));
872+
}
873+
}
874+
output ~= format("vsp = vsp + %d\n", scopeSize);
875+
output ~= "end\n";
876+
877+
inScope = false;
878+
variables = [];
879+
}
758880

759881
override void CompileSet(SetNode node) {
760882
if (VariableExists(node.var)) {

source/backends/rm86.d

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,17 @@ class BackendRM86 : CompilerBackend {
194194

195195
override void BeginMain() {
196196
output ~= "__calmain:\n";
197+
198+
// call globals
199+
foreach (name, global ; globals) {
200+
if (global.type.hasInit) {
201+
output ~= format(
202+
"mov word [si], word __global_%s\n", name.Sanitise()
203+
);
204+
output ~= "add si, 2\n";
205+
output ~= format("call __type_init_%s\n", global.type.name.Sanitise());
206+
}
207+
}
197208
}
198209

199210
void CallFunction(string name) {
@@ -598,14 +609,6 @@ class BackendRM86 : CompilerBackend {
598609
if (!orgSet) {
599610
Warn(node.error, "Declaring global variables without a set org value");
600611
}
601-
602-
if (global.type.hasInit) {
603-
output ~= format(
604-
"mov word [si], word __global_%s\n", node.name.Sanitise()
605-
);
606-
output ~= "add si, 2\n";
607-
output ~= format("call __type_init_%s\n", global.type.name.Sanitise());
608-
}
609612
}
610613
}
611614

@@ -989,7 +992,9 @@ class BackendRM86 : CompilerBackend {
989992
Error(node.error, "Can't set struct value");
990993
}
991994

992-
string addr = var.offset == 0? "sp" : format("sp + %d", var.offset);
995+
output ~= "mov bx, sp\n";
996+
997+
string addr = var.offset == 0? "bx" : format("bx + %d", var.offset);
993998

994999
switch (var.type.size) {
9951000
case 1: output ~= format("mov [%s], al\n", addr); break;

source/backends/uxn.d

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,13 @@ class BackendUXN : CompilerBackend {
176176

177177
override void BeginMain() {
178178
output ~= "@calmain\n";
179+
180+
foreach (name, global ; globals) {
181+
if (global.type.hasInit) {
182+
output ~= format(";global_%s\n", name.Sanitise());
183+
output ~= format("type_init_%s\n", global.type.name.Sanitise());
184+
}
185+
}
179186
}
180187

181188
void CallFunction(string name) {
@@ -537,11 +544,6 @@ class BackendUXN : CompilerBackend {
537544
global.array = node.array;
538545
global.arraySize = node.arraySize;
539546
globals[node.name] = global;
540-
541-
if (global.type.hasInit) {
542-
output ~= format(";global_%s\n", node.name.Sanitise());
543-
output ~= format("type_init_%s\n", global.type.name.Sanitise());
544-
}
545547
}
546548
}
547549

source/backends/x86_64.d

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,17 @@ class BackendX86_64 : CompilerBackend {
282282

283283
override void BeginMain() {
284284
output ~= "__calmain:\n";
285+
286+
// call constructors
287+
foreach (name, global ; globals) {
288+
if (global.type.hasInit) {
289+
output ~= format(
290+
"mov qword [r15], qword __global_%s\n", name.Sanitise()
291+
);
292+
output ~= "add r15, 8\n";
293+
output ~= format("call __type_init_%s\n", global.type.name.Sanitise());
294+
}
295+
}
285296
}
286297

287298
void CallFunction(string name) {
@@ -676,7 +687,7 @@ class BackendX86_64 : CompilerBackend {
676687
// create scope
677688
auto oldVars = variables.dup;
678689
auto oldSize = GetStackSize();
679-
690+
680691
foreach (ref inode ; node.doElse) {
681692
compiler.CompileNode(inode);
682693
}
@@ -800,14 +811,6 @@ class BackendX86_64 : CompilerBackend {
800811
global.array = node.array;
801812
global.arraySize = node.arraySize;
802813
globals[node.name] = global;
803-
804-
if (global.type.hasInit) { // call constructor
805-
output ~= format(
806-
"mov qword [r15], qword __global_%s\n", node.name.Sanitise()
807-
);
808-
output ~= "add r15, 8\n";
809-
output ~= format("call __type_init_%s\n", global.type.name.Sanitise());
810-
}
811814
}
812815
}
813816

0 commit comments

Comments
 (0)