Skip to content

Commit

Permalink
fixed globals
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli committed Dec 14, 2023
1 parent 24f2010 commit 64d8995
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 12 deletions.
41 changes: 34 additions & 7 deletions self_hosted/create_llvm_ir.jou
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class AstToIR:
for i = 0; i < self->n_local_vars; i++:
if strcmp(self->local_vars[i].name, name) == 0:
return self->local_vars[i].pointer
assert False
return NULL

def declare_function(self, sig: Signature*) -> LLVMValue*:
full_name: byte[200]
Expand Down Expand Up @@ -365,7 +365,13 @@ class AstToIR:

def do_address_of_expression(self, ast: AstExpression*) -> LLVMValue*:
if ast->kind == AstExpressionKind::GetVariable:
return self->get_local_var_pointer(ast->varname)
local_var = self->get_local_var_pointer(ast->varname)
if local_var != NULL:
return local_var

global_var = LLVMGetNamedGlobal(self->module, ast->varname)
assert global_var != NULL
return global_var

if ast->kind == AstExpressionKind::GetClassField:
lhs_type = self->function_or_method_types->get_expression_types(ast->class_field.instance)->original_type
Expand Down Expand Up @@ -625,6 +631,7 @@ class AstToIR:

elif ast->kind == AstExpressionKind::Self:
self_ptr = self->get_local_var_pointer("self")
assert self_ptr != NULL
result = LLVMBuildLoad(self->builder, self_ptr, "self")

elif ast->kind == AstExpressionKind::And:
Expand Down Expand Up @@ -746,6 +753,7 @@ class AstToIR:
elif ast->kind == AstStatementKind::DeclareLocalVar:
if ast->var_declaration.value != NULL:
target_pointer = self->get_local_var_pointer(ast->var_declaration.name)
assert target_pointer != NULL
value = self->do_expression(ast->var_declaration.value)
LLVMBuildStore(self->builder, value, target_pointer)
elif ast->kind == AstStatementKind::If:
Expand Down Expand Up @@ -820,27 +828,46 @@ class AstToIR:
self->function_or_method_types = NULL


# This distinguishes defined global variables from:
# - imported global variables
# - declared global variables
def file_defines_global_var(ast: AstFile*, name: byte*) -> bool:
for s = ast->body.statements; s < &ast->body.statements[ast->body.nstatements]; s++:
if s->kind == AstStatementKind::GlobalVariableDefinition and strcmp(s->var_declaration.name, name) == 0:
return True
return False


def create_llvm_ir(ast: AstFile*, ft: FileTypes*) -> LLVMModule*:
module = LLVMModuleCreateWithName(ast->path)
LLVMSetTarget(module, target.triple)
LLVMSetDataLayout(module, target.data_layout)

for v = ft->globals; v < &ft->globals[ft->nglobals]; v++:
t = type_to_llvm(v->type)
globalptr = LLVMAddGlobal(module, t, v->name)
if file_defines_global_var(ast, v->name):
LLVMSetInitializer(globalptr, LLVMConstNull(t))

a2i = AstToIR{
module = module,
builder = LLVMCreateBuilder(),
file_types = ft
}

for i = 0; i < ast->body.nstatements; i++:
if ast->body.statements[i].kind == AstStatementKind::Function and ast->body.statements[i].function.body.nstatements > 0:
a2i.define_function_or_method(&ast->body.statements[i].function, NULL)
elif ast->body.statements[i].kind == AstStatementKind::Class:
classdef = &ast->body.statements[i].classdef
for s = ast->body.statements; s < &ast->body.statements[ast->body.nstatements]; s++:
if s->kind == AstStatementKind::Function and s->function.body.nstatements > 0:
a2i.define_function_or_method(&s->function, NULL)
elif s->kind == AstStatementKind::Class:
classdef = &s->classdef
class_type = ft->find_type(classdef->name)
assert class_type != NULL
for k = 0; k < classdef->nmembers; k++:
if classdef->members[k].kind == AstClassMemberKind::Method:
a2i.define_function_or_method(&classdef->members[k].method, class_type)
else:
# TODO: need to handle some others?
pass

LLVMDisposeBuilder(a2i.builder)
return module
4 changes: 0 additions & 4 deletions self_hosted/runs_wrong.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ tests/other_errors/missing_return.jou
tests/other_errors/missing_value_in_return.jou
tests/other_errors/noreturn_but_return_with_value.jou
tests/other_errors/noreturn_but_return_without_value.jou
tests/other_errors/var_shadow.jou
tests/should_succeed/compiler_cli.jou
tests/should_succeed/global.jou
tests/should_succeed/global_bug.jou
tests/should_succeed/implicit_conversions.jou
tests/should_succeed/linked_list.jou
tests/should_succeed/pointer.jou
Expand All @@ -17,6 +14,5 @@ tests/should_succeed/stderr.jou
tests/should_succeed/unused_import.jou
tests/wrong_type/cannot_be_indexed.jou
tests/wrong_type/index.jou
stdlib/_macos_startup.jou
tests/syntax_error/assign_to_None.jou
tests/syntax_error/None_as_value.jou
4 changes: 3 additions & 1 deletion self_hosted/typecheck.jou
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,9 @@ class Stage3TypeChecker:
local_var = self->current_function_or_method->find_local_var(name)
if local_var != NULL:
return local_var->type
# TODO: check global vars (they don't exist yet)
for i = 0; i < self->file_types->nglobals; i++:
if strcmp(self->file_types->globals[i].name, name) == 0:
return self->file_types->globals[i].type
return NULL

def find_function_or_method(self, self_type: Type*, name: byte*) -> Signature*:
Expand Down

0 comments on commit 64d8995

Please sign in to comment.