aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMustafa Quraish <[email protected]>2022-02-03 03:42:41 -0500
committerMustafa Quraish <[email protected]>2022-02-03 03:42:41 -0500
commit3a7588e5c5b7718012917b608e2346dc066cecc2 (patch)
treeaa88655cf4210d5256377ab44ec1915a0bcebcfc /src
parentMove builtins to a separate file (diff)
downloadcup-3a7588e5c5b7718012917b608e2346dc066cecc2.tar.xz
cup-3a7588e5c5b7718012917b608e2346dc066cecc2.zip
Remove `putc` intrinsic and replace with `write(fd, buf, size)`
`putc`, `puts`, and `putnum` in `std/common.cup` are now implemented in terms of the `write()` syscall.
Diffstat (limited to 'src')
-rw-r--r--src/builtins.c10
-rw-r--r--src/generator.c20
-rw-r--r--src/types.c8
-rw-r--r--src/types.h2
4 files changed, 30 insertions, 10 deletions
diff --git a/src/builtins.c b/src/builtins.c
index 591caeb..3922d54 100644
--- a/src/builtins.c
+++ b/src/builtins.c
@@ -29,11 +29,13 @@ void initialize_builtins()
push_builtin(node);
node = Node_new(AST_BUILTIN);
- node->func.name = "putc";
+ node->func.name = "write";
node->func.return_type = type_new(TYPE_INT);
- node->func.num_args = 1;
- node->func.args = (Variable *)calloc(sizeof(Variable), 2);
- node->func.args[0] = (Variable){"arg", type_new(TYPE_INT), 0};
+ node->func.num_args = 3;
+ node->func.args = (Variable *)calloc(sizeof(Variable), 3);
+ node->func.args[0] = (Variable){"fd", type_new(TYPE_INT), 0};
+ node->func.args[1] = (Variable){"buf", type_new_ptr(TYPE_CHAR), 0};
+ node->func.args[2] = (Variable){"size", type_new(TYPE_INT), 0};
push_builtin(node);
}
diff --git a/src/generator.c b/src/generator.c
index f422657..aace3bc 100644
--- a/src/generator.c
+++ b/src/generator.c
@@ -170,6 +170,15 @@ void generate_expr_into_rax(Node *expr, FILE *out)
fprintf(out, " cqo\n");
fprintf(out, " idiv rbx\n");
+ } else if (expr->type == OP_MOD) {
+ generate_expr_into_rax(expr->binary.right, out);
+ fprintf(out, " push rax\n");
+ generate_expr_into_rax(expr->binary.left, out);
+ fprintf(out, " pop rbx\n");
+ fprintf(out, " cqo\n");
+ fprintf(out, " idiv rbx\n");
+ fprintf(out, " mov rax, rdx\n");
+
} else if (expr->type == OP_MUL) {
generate_expr_into_rax(expr->binary.right, out);
fprintf(out, " push rax\n");
@@ -507,13 +516,12 @@ void generate_builtins(FILE *out)
/////////////////////////////////////////////////////////////////
- // Print out a single character
+ // Write syscall
fprintf(out,
- "func_putc:\n"
- " mov rdi, 1\n" // stdout
- " mov rsi, rsp\n"
- " add rsi, 8\n"
- " mov rdx, 1\n" // 1 byte
+ "func_write:\n"
+ " mov rdi, [rsp+8]\n" // stdout
+ " mov rsi, [rsp+16]\n"
+ " mov rdx, [rsp+24]\n" // 1 byte
);
make_syscall(SYS_write, out);
fprintf(out, " ret\n");
diff --git a/src/types.c b/src/types.c
index 31edc4b..b2709f8 100644
--- a/src/types.c
+++ b/src/types.c
@@ -59,6 +59,14 @@ Type *type_new(DataType type)
return self;
}
+Type *type_new_ptr(DataType type)
+{
+ Type *self = type_new(TYPE_PTR);
+ self->ptr = type_new(type);
+ return self;
+}
+
+
bool is_string_type(Type *type)
{
return type
diff --git a/src/types.h b/src/types.h
index a1f6923..73b5b63 100644
--- a/src/types.h
+++ b/src/types.h
@@ -19,6 +19,8 @@ typedef struct data_type_node {
} Type;
Type *type_new(DataType type);
+Type *type_new_ptr(DataType type);
+
i64 size_for_type(Type *type);
char *type_to_str(Type *type);