aboutsummaryrefslogtreecommitdiff
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
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.
-rw-r--r--src/builtins.c10
-rw-r--r--src/generator.c20
-rw-r--r--src/types.c8
-rw-r--r--src/types.h2
-rw-r--r--std/common.cup22
-rwxr-xr-xtests/builtins.sh35
6 files changed, 47 insertions, 50 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);
diff --git a/std/common.cup b/std/common.cup
index b5e0e9f..865e8c3 100644
--- a/std/common.cup
+++ b/std/common.cup
@@ -62,12 +62,24 @@ fn streq(s1: char *, s2: char *): int {
return *s1 == *s2;
}
-// TODO: This should call fwrite() directly at some point.
fn puts(c: char *) {
let len: int = strlen(c);
- let i: int = 0;
+ write(0, c, len);
+}
- for (i = 0; i < len; i = i + 1) {
- putc(c[i]);
+fn strrev(s: char *) {
+ let len: int = strlen(s);
+ let i: int = 0;
+ let j: int = len - 1;
+ while (i < j) {
+ let tmp: char = s[i];
+ s[i] = s[j];
+ s[j] = tmp;
+ i = i + 1;
+ j = j - 1;
}
-} \ No newline at end of file
+}
+
+fn putc(c: char) {
+ write(0, &c, 1);
+}
diff --git a/tests/builtins.sh b/tests/builtins.sh
index c37cc2e..4628f70 100755
--- a/tests/builtins.sh
+++ b/tests/builtins.sh
@@ -31,38 +31,3 @@ assert_stdout_text \
"18446744073709551615"
echo " OK"
-
-echo -n "- putc: "
-assert_stdout_text \
-"fn main() {
- putc(65);
-}" \
-"A"
-
-assert_stdout_text \
-"fn main(a: int) {
- let i: int = 65;
- for (; i < 65 + 26; i = i + 1)
- putc(i);
-}" \
-"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-
-assert_stdout_text \
-"fn main() {
- putc(72);
- putc(101);
- putc(108);
- putc(108);
- putc(111);
- putc(44);
- putc(32);
- putc(87);
- putc(111);
- putc(114);
- putc(108);
- putc(100);
- putc(33);
-}" \
-"Hello, World!"
-
-echo " OK" \ No newline at end of file