Skip to content

Commit 0b7bb24

Browse files
authored
Merge pull request #16 from callisto-lang/FunctionParameters2
Function parameters
2 parents 2c0f4b0 + 0aa36d6 commit 0b7bb24

File tree

7 files changed

+208
-9
lines changed

7 files changed

+208
-9
lines changed

source/app.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ int main(string[] args) {
284284
break;
285285
}
286286
case "--help": {
287-
writeln(usage.strip());
287+
writefln(usage.strip(), args[0]);
288288
return 0;
289289
}
290290
default: {

source/backends/arm64.d

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,44 @@ class BackendARM64 : CompilerBackend {
534534
output ~= format("%s:\n", symbol);
535535
output ~= "str lr, [x20, #-8]!\n";
536536

537+
// allocate parameters
538+
size_t paramSize;
539+
foreach (ref type ; node.paramTypes) {
540+
if (!TypeExists(type)) {
541+
Error(node.error, "Type '%s' doesn't exist", type);
542+
}
543+
544+
paramSize += GetType(type).size;
545+
}
546+
if (paramSize > 0) {
547+
output ~= format("sub x20, x20, #%d\n", paramSize);
548+
foreach (ref var ; variables) {
549+
var.offset += paramSize;
550+
}
551+
552+
size_t offset;
553+
foreach (i, ref type ; node.paramTypes) {
554+
auto param = node.params[i];
555+
Variable var;
556+
557+
var.name = param;
558+
var.type = GetType(type);
559+
var.offset = cast(uint) offset;
560+
offset += var.Size();
561+
variables ~= var;
562+
}
563+
564+
// copy data to parameters
565+
output ~= format("sub x9, x19, #%d\n", paramSize);
566+
output ~= "mov x10, x20\n";
567+
output ~= format("mov x11, #%d\n", paramSize);
568+
output ~= "1:\n";
569+
output ~= "ldrb w12, [x9], #1\n";
570+
output ~= "strb w12, [x10], #1\n";
571+
output ~= "subs x11, x11, #1\n";
572+
output ~= "bne 1b\n";
573+
}
574+
537575
foreach (ref inode ; node.nodes) {
538576
compiler.CompileNode(inode);
539577
}

source/backends/lua.d

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,42 @@ class BackendLua : CompilerBackend {
326326
words[node.name] = Word(WordType.Callisto, false);
327327

328328
output ~= format("function func__%s()\n", node.name.Sanitise());
329+
330+
// allocate parameters
331+
size_t paramSize;
332+
foreach (ref type ; node.paramTypes) {
333+
if (!TypeExists(type)) {
334+
Error(node.error, "Type '%s' doesn't exist", type);
335+
}
336+
337+
paramSize += GetType(type).size;
338+
}
339+
if (paramSize > 0) {
340+
output ~= format("vsp = vsp - %d\n", paramSize);
341+
foreach (ref var ; variables) {
342+
var.offset += paramSize;
343+
}
344+
345+
size_t offset;
346+
foreach (i, ref type ; node.paramTypes) {
347+
auto param = node.params[i];
348+
Variable var;
349+
350+
var.name = param;
351+
var.type = GetType(type);
352+
var.offset = cast(uint) offset;
353+
offset += var.Size();
354+
variables ~= var;
355+
}
356+
357+
// copy data to parameters
358+
output ~= format("
359+
for i = 1, %d do
360+
mem[vsp + (i - 1)] = mem[(dsp - %d) + (i - 1)]
361+
end
362+
", paramSize, paramSize);
363+
}
364+
329365
foreach (ref inode ; node.nodes) {
330366
compiler.CompileNode(inode);
331367
}

source/backends/rm86.d

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,42 @@ class BackendRM86 : CompilerBackend {
409409

410410
output ~= format("%s:\n", symbol);
411411

412+
// allocate parameters
413+
size_t paramSize;
414+
foreach (ref type ; node.paramTypes) {
415+
if (!TypeExists(type)) {
416+
Error(node.error, "Type '%s' doesn't exist", type);
417+
}
418+
419+
paramSize += GetType(type).size;
420+
}
421+
if (paramSize > 0) {
422+
output ~= format("sub sp, %d\n", paramSize);
423+
foreach (ref var ; variables) {
424+
var.offset += paramSize;
425+
}
426+
427+
size_t offset;
428+
foreach (i, ref type ; node.paramTypes) {
429+
auto param = node.params[i];
430+
Variable var;
431+
432+
var.name = param;
433+
var.type = GetType(type);
434+
var.offset = cast(uint) offset;
435+
offset += var.Size();
436+
variables ~= var;
437+
}
438+
439+
// copy data to parameters
440+
output ~= "mov ax, si\n";
441+
output ~= format("sub si, %d\n", paramSize);
442+
output ~= "mov di, sp\n";
443+
output ~= format("mov cx, %d\n", paramSize);
444+
output ~= "rep movsb\n";
445+
output ~= "mov si, ax\n";
446+
}
447+
412448
foreach (ref inode ; node.nodes) {
413449
compiler.CompileNode(inode);
414450
}

source/backends/uxn.d

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,41 @@ class BackendUXN : CompilerBackend {
351351

352352
output ~= format("@%s\n", symbol);
353353

354+
// allocate parameters
355+
size_t paramSize;
356+
foreach (ref type ; node.paramTypes) {
357+
if (!TypeExists(type)) {
358+
Error(node.error, "Type '%s' doesn't exist", type);
359+
}
360+
361+
paramSize += GetType(type).size;
362+
}
363+
if (paramSize > 0) {
364+
output ~= format(".vsp LDZ2 #%.4x SUB2 .vsp STZ2\n", paramSize);
365+
foreach (ref var ; variables) {
366+
var.offset += paramSize;
367+
}
368+
369+
size_t offset;
370+
foreach (i, ref type ; node.paramTypes) {
371+
auto param = node.params[i];
372+
Variable var;
373+
374+
var.name = param;
375+
var.type = GetType(type);
376+
var.offset = cast(uint) offset;
377+
offset += var.Size();
378+
variables ~= var;
379+
}
380+
381+
// copy all parameters
382+
foreach_reverse (ref param ; node.params) {
383+
auto setNode = new SetNode(node.error);
384+
setNode.var = param;
385+
CompileSet(setNode);
386+
}
387+
}
388+
354389
foreach (ref inode ; node.nodes) {
355390
compiler.CompileNode(inode);
356391
}

source/backends/x86_64.d

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,41 @@ class BackendX86_64 : CompilerBackend {
624624

625625
output ~= format("%s:\n", symbol);
626626

627+
// allocate parameters
628+
size_t paramSize;
629+
foreach (ref type ; node.paramTypes) {
630+
if (!TypeExists(type)) {
631+
Error(node.error, "Type '%s' doesn't exist", type);
632+
}
633+
634+
paramSize += GetType(type).size;
635+
}
636+
if (paramSize > 0) {
637+
output ~= format("sub rsp, %d\n", paramSize);
638+
foreach (ref var ; variables) {
639+
var.offset += paramSize;
640+
}
641+
642+
size_t offset;
643+
foreach (i, ref type ; node.paramTypes) {
644+
auto param = node.params[i];
645+
Variable var;
646+
647+
var.name = param;
648+
var.type = GetType(type);
649+
var.offset = cast(uint) offset;
650+
offset += var.Size();
651+
variables ~= var;
652+
}
653+
654+
// copy data to parameters
655+
output ~= "mov rsi, r15\n";
656+
output ~= format("sub rsi, %d\n", paramSize);
657+
output ~= "mov rdi, rsp\n";
658+
output ~= format("mov rcx, %d\n", paramSize);
659+
output ~= "rep movsb\n";
660+
}
661+
627662
foreach (ref inode ; node.nodes) {
628663
compiler.CompileNode(inode);
629664
}

source/parser.d

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,25 @@ class IntegerNode : Node {
7979
}
8080

8181
class FuncDefNode : Node {
82-
string name;
83-
Node[] nodes;
84-
bool inline;
85-
bool raw;
82+
string name;
83+
Node[] nodes;
84+
bool inline;
85+
bool raw;
86+
string[] paramTypes;
87+
string[] params;
8688

8789
this(ErrorInfo perror) {
8890
type = NodeType.FuncDef;
8991
error = perror;
9092
}
9193

9294
override string toString() {
93-
string ret = format("func %s\n", name);
95+
string ret = format("func %s", name);
96+
97+
foreach (i, ref param ; params) {
98+
ret ~= format(" %s %s", paramTypes[i], param);
99+
}
100+
ret ~= " begin\n";
94101

95102
foreach (ref node ; nodes) {
96103
ret ~= " " ~ node.toString() ~ '\n';
@@ -526,6 +533,12 @@ class Parser {
526533
}
527534
}
528535

536+
bool IsIdentifier(string identifier) {
537+
return
538+
(tokens[i].type == TokenType.Identifier) &&
539+
(tokens[i].contents == identifier);
540+
}
541+
529542
Node ParseFuncDef(bool inline) {
530543
auto ret = new FuncDefNode(GetError());
531544
ret.inline = inline;
@@ -543,10 +556,16 @@ class Parser {
543556
ret.name = tokens[i].contents;
544557

545558
Next();
546-
Expect(TokenType.Identifier);
547-
if (tokens[i].contents != "begin") {
548-
Error("Expected begin keyword"); // TODO: add parameters
559+
560+
while (!IsIdentifier("begin")) {
561+
Expect(TokenType.Identifier);
562+
ret.paramTypes ~= tokens[i].contents;
563+
Next();
564+
Expect(TokenType.Identifier);
565+
ret.params ~= tokens[i].contents;
566+
Next();
549567
}
568+
550569
Next();
551570

552571
while (true) {

0 commit comments

Comments
 (0)