Skip to content

Commit

Permalink
add function pointers
Browse files Browse the repository at this point in the history
  • Loading branch information
MESYETI committed Jun 6, 2024
1 parent 7d6275b commit 00cb242
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 26 deletions.
8 changes: 8 additions & 0 deletions examples/funcPointers.cal
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
include "cores/select.cal"
include "std/io.cal"

func sayHello begin
"Hello!\n" printstr
end

&sayHello call
10 changes: 4 additions & 6 deletions source/app.d
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import std.process;
import std.algorithm;
import callisto.compiler;
import callisto.language;
import callisto.optimiser;
import callisto.codeRemover;
import callisto.preprocessor;
import callisto.backends.uxn;
import callisto.backends.y32;
Expand Down Expand Up @@ -270,11 +270,9 @@ int main(string[] args) {
return 1;
}

if (optimise) {
auto optimiser = new Optimiser();
optimiser.Run(nodes);
nodes = optimiser.res;
}
/*auto codeRemover = new CodeRemover();
codeRemover.Run(nodes);
nodes = codeRemover.res;*/

compiler.versions = preproc.versions;

Expand Down
16 changes: 16 additions & 0 deletions source/backends/linux86.d
Original file line number Diff line number Diff line change
Expand Up @@ -743,4 +743,20 @@ class BackendLinux86 : CompilerBackend {
output ~= format("extern %s\n", node.func);
}
}

override void CompileCall(WordNode node) {
output ~= "sub r15, 8\n";
output ~= "mov rax, [r15]\n";
output ~= "call rax\n";
}

override void CompileFuncAddr(FuncAddrNode node) {
if (node.func !in words) {
Error(node.error, "Function '%s' doesn't exist");
}

output ~= format("mov rax, __func__%s\n", node.func.Sanitise());
output ~= "mov [r15], rax\n";
output ~= "add r15, 8\n";
}
}
18 changes: 17 additions & 1 deletion source/backends/rm86.d
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ class BackendRM86 : CompilerBackend {
output ~= "ret\n";

foreach (name, var ; globals) {
output ~= format("__global_%s: times %d db 0\n", name, var.Size());
output ~= format("__global_%s: times %d db 0\n", name.Sanitise(), var.Size());
}

foreach (i, ref array ; arrays) {
Expand Down Expand Up @@ -652,4 +652,20 @@ class BackendRM86 : CompilerBackend {
word.raw = node.raw;
words[node.func] = word;
}

override void CompileCall(WordNode node) {
output ~= "sub si, 2\n";
output ~= "mov ax, [si]\n";
output ~= "call ax\n";
}

override void CompileFuncAddr(FuncAddrNode node) {
if (node.func !in words) {
Error(node.error, "Function '%s' doesn't exist");
}

output ~= format("mov ax, __func__%s\n", node.func.Sanitise());
output ~= "mov [si], ax\n";
output ~= "add si, 2\n";
}
}
18 changes: 17 additions & 1 deletion source/backends/uxn.d
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class BackendUXN : CompilerBackend {
output ~= "JMP2r\n";

foreach (name, var ; globals) {
output ~= format("@global_%s", name);
output ~= format("@global_%s", name.Sanitise());

foreach (i ; 0 .. var.Size()) {
output ~= " #00";
Expand Down Expand Up @@ -226,6 +226,10 @@ class BackendUXN : CompilerBackend {
}

override void CompileInteger(IntegerNode node) {
if (node.value > 0xFFFF) {
Error(node.error, "Value is too big for 16-bit target");
}

output ~= format("#%.4x\n", node.value);
}

Expand Down Expand Up @@ -637,4 +641,16 @@ class BackendUXN : CompilerBackend {
word.raw = node.raw;
words[node.func] = word;
}

override void CompileCall(WordNode node) {
output ~= "JSR2\n";
}

override void CompileFuncAddr(FuncAddrNode node) {
if (node.func !in words) {
Error(node.error, "Function '%s' doesn't exist");
}

output ~= format(";func__%s\n", node.func.Sanitise());
}
}
8 changes: 8 additions & 0 deletions source/backends/y32.d
Original file line number Diff line number Diff line change
Expand Up @@ -272,4 +272,12 @@ class BackendY32 : CompilerBackend {
override void CompileExtern(ExternNode node) {
assert(0);
}

override void CompileCall(WordNode node) {
assert(0);
}

override void CompileFuncAddr(FuncAddrNode node) {
assert(0);
}
}
15 changes: 11 additions & 4 deletions source/optimiser.d → source/codeRemover.d
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
module callisto.optimiser;
module callisto.codeRemover;

import std.stdio;
import std.format;
import std.algorithm;
import callisto.error;
import callisto.parser;

class OptimiserError : Exception {
class CodeRemoverError : Exception {
this() {
super("", "", 0);
}
}

class Optimiser {
class CodeRemover {
Node[] res;
string[] usedFunctions;
Node[][string] functions;
string[] funcStack;

this() {

Expand All @@ -24,7 +25,7 @@ class Optimiser {
final void Error(Char, A...)(ErrorInfo error, in Char[] fmt, A args) {
ErrorBegin(error);
stderr.writeln(format(fmt, args));
throw new OptimiserError();
throw new CodeRemoverError();
}

void FindFunctions(Node[] nodes) {
Expand All @@ -39,7 +40,13 @@ class Optimiser {
continue;
}

if (funcStack.canFind(node.name)) {
return;
}

funcStack ~= node.name;
FindFunctions(functions[node.name]);
funcStack = funcStack[0 .. $ - 1];
break;
}
case NodeType.If: {
Expand Down
24 changes: 14 additions & 10 deletions source/compiler.d
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class CompilerBackend {
abstract void CompileUnion(UnionNode node);
abstract void CompileAlias(AliasNode node);
abstract void CompileExtern(ExternNode node);
abstract void CompileCall(WordNode node);
abstract void CompileFuncAddr(FuncAddrNode node);

final void Error(Char, A...)(ErrorInfo error, in Char[] fmt, A args) {
ErrorBegin(error);
Expand Down Expand Up @@ -81,9 +83,10 @@ class Compiler {
auto node = cast(WordNode) inode;

switch (node.name) {
case "return": backend.CompileReturn(node); break;
case "return": backend.CompileReturn(node); break;
case "continue": backend.CompileContinue(node); break;
case "break": backend.CompileBreak(node); break;
case "break": backend.CompileBreak(node); break;
case "call": backend.CompileCall(node); break;
case "error": backend.Error(node.error, "Error thrown by code"); break;
default: backend.CompileWord(node);
}
Expand Down Expand Up @@ -159,14 +162,15 @@ class Compiler {
}
break;
}
case NodeType.Array: backend.CompileArray(cast(ArrayNode) inode); break;
case NodeType.String: backend.CompileString(cast(StringNode) inode); break;
case NodeType.Struct: backend.CompileStruct(cast(StructNode) inode); break;
case NodeType.Const: backend.CompileConst(cast(ConstNode) inode); break;
case NodeType.Enum: backend.CompileEnum(cast(EnumNode) inode); break;
case NodeType.Union: backend.CompileUnion(cast(UnionNode) inode); break;
case NodeType.Alias: backend.CompileAlias(cast(AliasNode) inode); break;
case NodeType.Extern: backend.CompileExtern(cast(ExternNode) inode); break;
case NodeType.Array: backend.CompileArray(cast(ArrayNode) inode); break;
case NodeType.String: backend.CompileString(cast(StringNode) inode); break;
case NodeType.Struct: backend.CompileStruct(cast(StructNode) inode); break;
case NodeType.Const: backend.CompileConst(cast(ConstNode) inode); break;
case NodeType.Enum: backend.CompileEnum(cast(EnumNode) inode); break;
case NodeType.Union: backend.CompileUnion(cast(UnionNode) inode); break;
case NodeType.Alias: backend.CompileAlias(cast(AliasNode) inode); break;
case NodeType.Extern: backend.CompileExtern(cast(ExternNode) inode); break;
case NodeType.FuncAddr: backend.CompileFuncAddr(cast(FuncAddrNode) inode); break;
default: {
backend.Error(inode.error, "Unimplemented node '%s'", inode.type);
}
Expand Down
8 changes: 7 additions & 1 deletion source/lexer.d
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ enum TokenType {
String,
Identifier,
LSquare,
RSquare
RSquare,
Ampersand
}

struct Token {
Expand Down Expand Up @@ -202,6 +203,11 @@ class Lexer {
col = 0;
break;
}
case '&': {
AddReading();
AddToken(TokenType.Ampersand);
break;
}
case '\'': {
Next();
char ch = code[i];
Expand Down
5 changes: 5 additions & 0 deletions source/optimise.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module callisto.optimise;

class Optimiser {

}
30 changes: 27 additions & 3 deletions source/parser.d
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ enum NodeType {
Restrict,
Union,
Alias,
Extern
Extern,
FuncAddr
}

class Node {
Expand Down Expand Up @@ -410,6 +411,17 @@ class ExternNode : Node {
override string toString() => format("extern %s%s", raw? "" : "raw ", func);
}

class FuncAddrNode : Node {
string func;

this(ErrorInfo perror) {
type = NodeType.FuncAddr;
error = perror;
}

override string toString() => format("&%s", func);
}

class ParserError : Exception {
this() {
super("", "", 0);
Expand Down Expand Up @@ -958,6 +970,17 @@ class Parser {
return ret;
}

Node ParseFuncAddr() {
auto ret = new FuncAddrNode(GetError());
parsing = NodeType.FuncAddr;

Next();
Expect(TokenType.Identifier);
ret.func = tokens[i].contents;

return ret;
}

Node ParseStatement() {
switch (tokens[i].type) {
case TokenType.Integer: {
Expand Down Expand Up @@ -985,8 +1008,9 @@ class Parser {
default: return new WordNode(GetError(), tokens[i].contents);
}
}
case TokenType.LSquare: return ParseArray();
case TokenType.String: return ParseString();
case TokenType.LSquare: return ParseArray();
case TokenType.String: return ParseString();
case TokenType.Ampersand: return ParseFuncAddr();
default: {
Error("Unexpected %s", tokens[i].type);
}
Expand Down

0 comments on commit 00cb242

Please sign in to comment.