diff options
| author | Mustafa Quraish <[email protected]> | 2022-02-03 03:42:41 -0500 |
|---|---|---|
| committer | Mustafa Quraish <[email protected]> | 2022-02-03 03:42:41 -0500 |
| commit | 3a7588e5c5b7718012917b608e2346dc066cecc2 (patch) | |
| tree | aa88655cf4210d5256377ab44ec1915a0bcebcfc | |
| parent | Move builtins to a separate file (diff) | |
| download | cup-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.c | 10 | ||||
| -rw-r--r-- | src/generator.c | 20 | ||||
| -rw-r--r-- | src/types.c | 8 | ||||
| -rw-r--r-- | src/types.h | 2 | ||||
| -rw-r--r-- | std/common.cup | 22 | ||||
| -rwxr-xr-x | tests/builtins.sh | 35 |
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 |