aboutsummaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorMustafa Quraish <[email protected]>2022-02-07 23:07:57 -0500
committerMustafa Quraish <[email protected]>2022-02-08 02:07:18 -0500
commite5f2fac8c5ae5a1b74335816836872c2e24904e6 (patch)
treeed131049d39320967d8d18f65749c08ebb2f79a0 /compiler
parentMark bootstrap files as binary in `.gitattributes` (diff)
downloadcup-e5f2fac8c5ae5a1b74335816836872c2e24904e6.tar.xz
cup-e5f2fac8c5ae5a1b74335816836872c2e24904e6.zip
[cup] Add `>>` and `<<` operators, `fork()` buildin and `SYS_execve`HEADmaster
Diffstat (limited to 'compiler')
-rw-r--r--compiler/builtins.cup30
-rw-r--r--compiler/codegen.cup15
-rw-r--r--compiler/lexer.cup4
-rw-r--r--compiler/parser.cup2
4 files changed, 50 insertions, 1 deletions
diff --git a/compiler/builtins.cup b/compiler/builtins.cup
index 8aae3d9..bee24e0 100644
--- a/compiler/builtins.cup
+++ b/compiler/builtins.cup
@@ -18,7 +18,16 @@ fn builtin_create_syscall(name: char*, num_args: int) {
// Defined in `parser.cup`
fn constant_push(name: char*, val: int);
+const MACOS_SYSCALL_OFFSET = 33554432; // 0x2000000;
fn builtins_push_posix_constants() {
+
+ // TODO: make this permanent?
+ if (OS_IS_MACOS) {
+ constant_push("SYS_execve", 59 + MACOS_SYSCALL_OFFSET);
+ } else {
+ constant_push("SYS_execve", 59);
+ }
+
constant_push("SYS_read", SYS_read);
constant_push("SYS_write", SYS_write);
constant_push("SYS_exit", SYS_exit);
@@ -72,6 +81,14 @@ fn initialize_builtins() {
vector_push(node.d.func.args, variable_new("val", type_new(TYPE_ANY), 0));
vector_push(all_builtins, node);
+ // The return value of fork() is weird on macOS, parent/child is returned in rdx
+ // and the child pid is returned in rax, so we'll make our own wrapper.
+ node = node_new(AST_BUILTIN);
+ node.etyp = type_new(TYPE_INT);
+ node.d.func.name = "fork";
+ node.d.func.args = vector_new_sized(0);
+ vector_push(all_builtins, node);
+
builtin_create_syscall("syscall0", 0);
builtin_create_syscall("syscall1", 1);
builtin_create_syscall("syscall2", 2);
@@ -155,4 +172,17 @@ fn generate_builtins() {
emit_asm(" syscall\n");
emit_asm(" ret\n");
}
+
+ emit_asm("func_fork:\n");
+ emit_asm(" mov rdi, [rsp+8]\n");
+ emit_asm(" mov rax, "); emit_num(SYS_fork); emit_asm("\n");
+ emit_asm(" syscall\n");
+ if (OS_IS_MACOS) {
+ // If rdx is 0, we are in the child, so set rax to 0 to match Linux
+ emit_asm(" cmp rdx, 0\n");
+ emit_asm(" je .L1\n");
+ emit_asm(" mov rax, 0\n");
+ emit_asm(".L1:\n");
+ }
+ emit_asm(" ret\n");
} \ No newline at end of file
diff --git a/compiler/codegen.cup b/compiler/codegen.cup
index 67a401c..bf20a8b 100644
--- a/compiler/codegen.cup
+++ b/compiler/codegen.cup
@@ -142,6 +142,21 @@ fn generate_expr_into_rax(node: Node*) {
emit_asm(" pop rbx\n");
emit_asm(" sub rax, rbx\n");
+ } else if (node.typ == AST_LSHIFT) {
+ generate_expr_into_rax(node.d.binary.rhs);
+ emit_asm(" push rax\n");
+ generate_expr_into_rax(node.d.binary.lhs);
+ emit_asm(" pop rcx\n");
+ emit_asm(" shl rax, cl\n");
+
+
+ } else if (node.typ == AST_RSHIFT) {
+ generate_expr_into_rax(node.d.binary.rhs);
+ emit_asm(" push rax\n");
+ generate_expr_into_rax(node.d.binary.lhs);
+ emit_asm(" pop rcx\n");
+ emit_asm(" shr rax, cl\n");
+
} else if (node.typ == AST_DIV) {
generate_expr_into_rax(node.d.binary.rhs);
emit_asm(" push rax\n");
diff --git a/compiler/lexer.cup b/compiler/lexer.cup
index 9e967f8..e6d0c0b 100644
--- a/compiler/lexer.cup
+++ b/compiler/lexer.cup
@@ -138,12 +138,16 @@ fn lexer_next(lexer: Lexer*, token: Token*) {
}
else if (c == '<') {
+ if (lexer_peek_char(lexer, 1) == '<')
+ return lexer_make_token(lexer, token, TOKEN_LSHIFT, 2);
if (lexer_peek_char(lexer, 1) == '=')
return lexer_make_token(lexer, token, TOKEN_LEQ, 2);
return lexer_make_token(lexer, token, TOKEN_LT, 1);
}
else if (c == '>') {
+ if (lexer_peek_char(lexer, 1) == '>')
+ return lexer_make_token(lexer, token, TOKEN_RSHIFT, 2);
if (lexer_peek_char(lexer, 1) == '=')
return lexer_make_token(lexer, token, TOKEN_GEQ, 2);
return lexer_make_token(lexer, token, TOKEN_GT, 1);
diff --git a/compiler/parser.cup b/compiler/parser.cup
index d57885e..d3fa64f 100644
--- a/compiler/parser.cup
+++ b/compiler/parser.cup
@@ -482,7 +482,7 @@ fn parse_additive(lexer: Lexer*): Node* {
let lhs = parse_term(lexer);
lexer_peek(lexer, &token);
- while (token.typ == TOKEN_PLUS || token.typ == TOKEN_MINUS) {
+ while (token.typ == TOKEN_PLUS || token.typ == TOKEN_MINUS || token.typ == TOKEN_LSHIFT || token.typ == TOKEN_RSHIFT) {
lexer_next(lexer, &token);
let op = node_new(binary_token_to_op(token.typ));
let rhs = parse_term(lexer);