Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_library("sd-base"
analyzer/fn/fn_analyzer.c
analyzer/halts/halt_analyzer.c
analyzer/lv/lv_analyzer.c
analyzer/data/data_analyzer.c

#liveness
liveness/liveness.c
Expand All @@ -22,6 +23,7 @@ add_library("sd-base"
gen_tac/gen_tac_assignstmt.c
gen_tac/gen_tac_call.c
gen_tac/gen_tac_constvalue.c
gen_tac/gen_tac_const_data.c
gen_tac/gen_tac_expr.c
gen_tac/gen_tac_forstmt.c
gen_tac/gen_tac_ifstmt.c
Expand Down Expand Up @@ -67,6 +69,7 @@ add_library("sd-base"
x86_code_gen/compile_ir/compile_tac_call.c
x86_code_gen/compile_ir/compile_tac_icall.c
x86_code_gen/compile_ir/compile_tac_const_value.c
x86_code_gen/compile_ir/compile_tac_const_data.c
x86_code_gen/compile_ir/compile_tac_copy.c
x86_code_gen/compile_ir/compile_tac_goto.c
x86_code_gen/compile_ir/compile_tac_if_goto.c
Expand Down
30 changes: 30 additions & 0 deletions compiler/main/analyzer/data/data_analyzer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "ast/ast.h"

#include "tables/symtable/symtable.h"
#include "tables/data/data.h"

#include "data_analyzer.h"

#include "ast/visitor/visitor.h"

static void data_visitor(void* node, enum NODE_TYPE type, void* arg);

void analyze_data(struct ST* st, struct AST* ast) {

visit_ast(ast, data_visitor, st->data);
}

static void data_visitor(void* node, enum NODE_TYPE type, void* arg) {

struct DataTable* data = (struct DataTable*)arg;

if (type != NODE_STRINGCONST) { return; }

struct StringConst* sc = (struct StringConst*)node;

data_insert(data, sc->value);
}
10 changes: 10 additions & 0 deletions compiler/main/analyzer/data/data_analyzer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

// This analyzer module visits the AST
// to look for StringConst instances
// and adds them to DataTable

struct ST;
struct AST;

void analyze_data(struct ST* st, struct AST* ast);
5 changes: 5 additions & 0 deletions compiler/main/avr_code_gen/cg_avr.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

#include "tables/symtable/symtable.h"

Expand Down Expand Up @@ -91,6 +92,10 @@ bool compile_and_write_avr(struct AST* ast, struct Ctx* ctx) {

{
emit_defs(fout);

//TODO: figure out how to support something like .data on AVR.
assert(data_count(ctx_tables(ctx)->data) == 0);

ibu_write(ibu, fout);
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/main/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "analyzer/dead/dead_analyzer.h"
#include "analyzer/halts/halt_analyzer.h"
#include "analyzer/annotation/annotation_analyzer.h"
#include "analyzer/data/data_analyzer.h"

bool compile(struct Flags* flags) {

Expand Down Expand Up @@ -114,6 +115,7 @@ bool compile(struct Flags* flags) {
analyze_dead_code(ctx_tables(ctx), ast);
analyze_termination(ctx_tables(ctx));
analyze_annotations(ctx_tables(ctx), ast);
analyze_data(ctx_tables(ctx), ast);

bool success;
if (flags_x86(flags)) {
Expand Down
7 changes: 4 additions & 3 deletions compiler/main/derefll/derefll.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,10 @@ struct DerefLL* derefll_ctor_simplevar(struct SimpleVar* sv, struct Ctx* ctx) {
struct LVSTLine* line = lvst_get(lvst, sv->name);

// In case of array type, we need an additional deref,
// to get the pointer out of the stackframe.
// Deref is implicit for array type
if (line->type->array_type) {
// to get the pointer out of the stackframe, in case indices are present.
// That Deref is implicit for array type

if (line->type->array_type && sv->count_indices) {
derefll_append(res, derefll_deref());
}

Expand Down
3 changes: 3 additions & 0 deletions compiler/main/gen_tac/gen_tac.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,8 @@ bool tac_term_addr(struct TACBuffer* buffer, struct Term* t, struct Ctx* ctx);

void tac_constvalue(struct TACBuffer* buffer, struct ConstValue* c);

// @returns false on error
bool tac_const_data(struct TACBuffer* buffer, struct StringConst* c, struct Ctx* ctx);

//----
int int_value_from_const(struct ConstValue* cv);
24 changes: 24 additions & 0 deletions compiler/main/gen_tac/gen_tac_const_data.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <stdio.h>

#include "tables/symtable/symtable.h"
#include "tac/tac.h"
#include "tac/tacbuffer.h"
#include "gen_tac.h"

#include "tables/data/data.h"

bool tac_const_data(struct TACBuffer* buffer, struct StringConst* str, struct Ctx* ctx) {

const int32_t offset = data_string_offset(ctx_tables(ctx)->data, str->value);

if (offset < 0) {
fprintf(stderr, "%s:%s: could not find offset of '%s' in data table\n", __FILE__, __func__, str->value);
return false;
}

tacbuffer_append(
buffer,
makeTACConstData(make_temp(), offset));

return true;
}
4 changes: 1 addition & 3 deletions compiler/main/gen_tac/gen_tac_term.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ bool tac_term(struct TACBuffer* buffer, struct Term* t, struct Ctx* ctx) {
case 4: tac_call(buffer, t->ptr.m4, ctx); break;
case 5: tac_expr(buffer, t->ptr.m5, ctx); break;
case 6: tac_variable(buffer, t->ptr.m6, ctx); break;
case 8:
fprintf(stderr, "string const currently unsupported\n");
return false;
case 8: return tac_const_data(buffer, t->ptr.m8, ctx);
case 11:
fprintf(stderr, "Fatal Error. Lambdas should not exist at this stage.\n");
return false;
Expand Down
5 changes: 5 additions & 0 deletions compiler/main/typechecker/type_contains/tc_type_contains.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ static bool tc_pointer_type_contains(struct PointerType* expect, struct Type* ac

// integers can be used as pointers
if (actual->pointer_type == NULL) {

if (actual->array_type != NULL) {
return eq_type(expect->element_type, actual->array_type->element_type);
}

return is_integer_type(actual);
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/main/x86_code_gen/cg_x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ bool compile_and_write_x86(struct AST* ast, struct Ctx* ctx) {
return false;
}

data_write_data_segment(ctx_tables(ctx)->data, fout);

fprintf(fout, "section .text\n");
fprintf(fout, "global _start\n\n");

Expand Down
26 changes: 20 additions & 6 deletions compiler/main/x86_code_gen/cg_x86_basic_block.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,41 @@
#include "x86_code_gen/compile_ir/compile_tac.h"
#include "cg_x86_basic_block.h"

void emit_asm_x86_basic_block(struct BasicBlock* block, struct Ctx* ctx, struct IBuffer* ibu, struct RAT* rat, char* current_function_name) {
bool emit_asm_x86_basic_block(struct BasicBlock* block, struct Ctx* ctx, struct IBuffer* ibu, struct RAT* rat, char* current_function_name) {

bool success = false;

if (block == NULL) {
return;
return true;
}
if (block->visited_emit_asm) {
return;
return true;
}

block->visited_emit_asm = true;

for (size_t i = 0; i < tacbuffer_count(block->buffer); i++) {
struct TAC* t = tacbuffer_get(block->buffer, i);

emit_asm_x86_single_tac(rat, t, ctx, ibu, current_function_name);
success = emit_asm_x86_single_tac(rat, t, ctx, ibu, current_function_name);

if (!success) {
return false;
}
}

//false/default branch gets emitted first,
//because there is no label for it in a lot of cases
//this way we can avoid an extra jump that's really
//not necessary.
emit_asm_x86_basic_block(block->branch_2, ctx, ibu, rat, current_function_name);
emit_asm_x86_basic_block(block->branch_1, ctx, ibu, rat, current_function_name);
success = emit_asm_x86_basic_block(block->branch_2, ctx, ibu, rat, current_function_name);
if (!success) {
return false;
}
success = emit_asm_x86_basic_block(block->branch_1, ctx, ibu, rat, current_function_name);
if (!success) {
return false;
}

return true;
}
3 changes: 2 additions & 1 deletion compiler/main/x86_code_gen/cg_x86_basic_block.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@

struct IBuffer;

void emit_asm_x86_basic_block(struct BasicBlock* block, struct Ctx* ctx, struct IBuffer* ibu, struct RAT* rat, char* current_function_name);
// @returns false on error
bool emit_asm_x86_basic_block(struct BasicBlock* block, struct Ctx* ctx, struct IBuffer* ibu, struct RAT* rat, char* current_function_name);
5 changes: 4 additions & 1 deletion compiler/main/x86_code_gen/cg_x86_single_function.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ void compile_and_write_x86_single_function(struct Method* m, struct Ctx* ctx, st
rat_print(rat);
}

emit_asm_x86_basic_block(root, ctx, ibu, rat, current_function_name);
bool success = emit_asm_x86_basic_block(root, ctx, ibu, rat, current_function_name);

// TODO: propagate this error
assert(success);

//delete the basic block graph
for (int i = 0; i < nblocks; i++) {
Expand Down
1 change: 1 addition & 0 deletions compiler/main/x86_code_gen/cg_x86_single_tac.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ bool emit_asm_x86_single_tac(struct RAT* rat, struct TAC* tac, struct Ctx* ctx,

case TAC_COPY: compile_tac_copy_x86(rat, tac, ibu); break;
case TAC_CONST_VALUE: compile_tac_const_value_x86(rat, tac, ibu); break;
case TAC_CONST_DATA: compile_tac_const_data_x86(rat, tac, ctx, ibu); break;
case TAC_CALL: compile_tac_call_x86(rat, tac, ibu, ctx, current_function_name); break;
case TAC_ICALL: compile_tac_icall_x86(rat, tac, ibu, ctx, current_function_name); break;
case TAC_PARAM: compile_tac_param_x86(rat, tac, ibu); break;
Expand Down
1 change: 1 addition & 0 deletions compiler/main/x86_code_gen/compile_ir/compile_tac.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct ST;

void compile_tac_return_x86(struct RAT* rat, struct TAC* tac, struct Ctx* ctx, struct IBuffer* ibu);
void compile_tac_const_value_x86(struct RAT* rat, struct TAC* tac, struct IBuffer* ibu);
void compile_tac_const_data_x86(struct RAT* rat, struct TAC* tac, struct Ctx* ctx, struct IBuffer* ibu);

void compile_tac_copy_x86(struct RAT* rat, struct TAC* tac, struct IBuffer* ibu);
void compile_tac_load_local_addr_x86(struct RAT* rat, struct TAC* tac, struct Ctx* ctx, struct IBuffer* ibu);
Expand Down
30 changes: 30 additions & 0 deletions compiler/main/x86_code_gen/compile_ir/compile_tac_const_data.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <assert.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

#include "rat/rat.h"

#include "tables/symtable/symtable.h"
#include "tac/tac.h"
#include "x86_code_gen/compile_ir/compile_tac.h"

void compile_tac_const_data_x86(struct RAT* rat, struct TAC* tac, struct Ctx* ctx, struct IBuffer* ibu) {

const int reg = rat_get_register(rat, tac_dest(tac));

const uint64_t offset = tac_const_value(tac);

struct DataTable* data_table = ctx_tables(ctx)->data;

char* symbol = data_symbol(data_table, offset);

assert(symbol != NULL);

char* c;
asprintf(&c, "TAC_CONST_DATA %s", symbol);

mov_const_symbol(reg, symbol, c);

free(c);
}
8 changes: 8 additions & 0 deletions docs/html/tac.html
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,14 @@ <h3>Other</h3>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>TAC_CONST_DATA</td> <td>t1 = 0</td>
<td>TMP</td>
<td>-</td>
<td>offset into data table</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>TAC_NOP</td> <td>nop</td>
<td> - </td>
Expand Down
35 changes: 35 additions & 0 deletions examples/syscalls/read_file/read_file.dg
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
fn main () ~> int {

// since this is run as part of tests,
// the path needs to be relative from examples/
[char] filename = "syscalls/read_file/read_file.dg";
*char path = filename;
int fd = open(path, 0, 1);

if fd < 0 {
return 1;
}

char c = ' ';
*char ptr = &c;

read(fd, ptr, 1);
write(1, &c, 1);
read(fd, ptr, 1);
write(1, &c, 1);
read(fd, ptr, 1);
write(1, &c, 1);
read(fd, ptr, 1);
write(1, &c, 1);
read(fd, ptr, 1);
write(1, &c, 1);
read(fd, ptr, 1);
write(1, &c, 1);
read(fd, ptr, 1);
write(1, &c, 1);

c = '\n';
write(1, &c, 1);

return 0;
}
1 change: 1 addition & 0 deletions examples/syscalls/read_file/read_file.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fn main
14 changes: 14 additions & 0 deletions examples/syscalls/write_string/write_string.dg
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
fn main () ~> int {

[char] str1 = "Hello, ";
*char ptr = str1;

write(1, ptr, 7);

[char] str2 = "World!\n";
ptr = str2;

write(1, ptr, 7);

return 0;
}
1 change: 1 addition & 0 deletions examples/syscalls/write_string/write_string.exitcode
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
1 change: 1 addition & 0 deletions examples/syscalls/write_string/write_string.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello, World!
8 changes: 7 additions & 1 deletion stdlib/syscalls.dg
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@


@syscall
fn write(uint fd, *char buf, uint64 count) -> int {}
fn write(uint fd, *char buf, uint64 count) -> int64 {}

@syscall
fn open(*char filename, int flags, int mode) -> int {}

@syscall
fn read(int fd, *char buf, uint64 count) -> int64 {}

@syscall
fn exit(int code) -> int {}
2 changes: 2 additions & 0 deletions tables/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ add_library("sd-tables" STATIC
stst/stst.c
stst/stst_print.c

data/data.c

symtable/symtable.c
)

Expand Down
Loading