Skip to content

Commit

Permalink
Half of my work on self-hosted (#459)
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli authored Dec 16, 2023
1 parent 5e5691c commit fae5e3d
Show file tree
Hide file tree
Showing 13 changed files with 313 additions and 165 deletions.
7 changes: 4 additions & 3 deletions compare_compilers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ for arg in "$@"; do
done

if [ ${#files[@]} = 0 ]; then
# skip compiler_cli, because it has a race condition when two compilers simultaneously run it
# TODO: do not skip Advent Of Code files
files=( $(find stdlib examples tests -name '*.jou' | grep -v aoc2023 | sort) )
files=( $(find stdlib examples tests -name '*.jou' | grep -v aoc2023 | grep -v tests/should_succeed/compiler_cli | grep -v tests/crash | sort) )
fi
if [ ${#actions[@]} = 0 ]; then
actions=(tokenize parse run)
Expand Down Expand Up @@ -103,11 +104,11 @@ for action in ${actions[@]}; do
# Run compilers in parallel to speed up.
(
set +e
./jou $flag $file 2>&1 | grep -vE 'undefined reference to|multiple definition of|\bld: '
./jou $flag $file 2>&1 | grep -vE 'undefined reference to|multiple definition of|\bld: |compiler warning for file'
) > tmp/compare_compilers/compiler_written_in_c.txt &
(
set +e
./self_hosted_compiler $flag $file 2>&1 | grep -vE 'undefined reference to|multiple definition of|\bld: |linking failed'
./self_hosted_compiler $flag $file 2>&1 | grep -vE 'undefined reference to|multiple definition of|\bld: |linking failed|compiler warning for file'
) > tmp/compare_compilers/self_hosted.txt &
wait

Expand Down
135 changes: 84 additions & 51 deletions self_hosted/ast.jou
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,10 @@ class AstExpression:
float_or_double_text: byte[100]
operands: AstExpression* # Only for operators. Length is arity, see get_arity()

def print(self, tp: TreePrinter) -> None:
def print(self) -> None:
self->print_with_tree_printer(TreePrinter{})

def print_with_tree_printer(self, tp: TreePrinter) -> None:
printf("[line %d] ", self->location.lineno)
if self->kind == AstExpressionKind::String:
printf("\"")
Expand Down Expand Up @@ -181,7 +184,7 @@ class AstExpression:
elif self->kind == AstExpressionKind::Array:
printf("array\n")
for i = 0; i < self->array.length; i++:
self->array.items[i].print(tp.print_prefix(i == self->array.length-1))
self->array.items[i].print_with_tree_printer(tp.print_prefix(i == self->array.length-1))
elif self->kind == AstExpressionKind::Call:
if self->call.uses_arrow_operator:
printf("dereference and ")
Expand All @@ -204,12 +207,12 @@ class AstExpression:
if self->class_field.uses_arrow_operator:
printf("dereference and ")
printf("get class field \"%s\"\n", self->class_field.field_name)
self->class_field.instance->print(tp.print_prefix(True))
self->class_field.instance->print_with_tree_printer(tp.print_prefix(True))
elif self->kind == AstExpressionKind::As:
printf("as ")
self->as_expression->type.print(True)
printf("\n")
self->as_expression->value.print(tp.print_prefix(True))
self->as_expression->value.print_with_tree_printer(tp.print_prefix(True))
elif self->kind == AstExpressionKind::SizeOf:
printf("sizeof\n")
elif self->kind == AstExpressionKind::AddressOf:
Expand Down Expand Up @@ -258,7 +261,7 @@ class AstExpression:
printf("?????\n")

for i = 0; i < self->get_arity(); i++:
self->operands[i].print(tp.print_prefix(i == self->get_arity()-1))
self->operands[i].print_with_tree_printer(tp.print_prefix(i == self->get_arity()-1))

def free(self) -> None:
if self->kind == AstExpressionKind::Call:
Expand Down Expand Up @@ -367,12 +370,12 @@ class AstCall:
if self->method_call_self != NULL:
sub = tp.print_prefix(self->nargs == 0)
printf("self: ")
self->method_call_self->print(sub)
self->method_call_self->print_with_tree_printer(sub)

for i = 0; i < self->nargs; i++:
sub = tp.print_prefix(i == self->nargs - 1)
printf("argument %d: ", i)
self->args[i].print(sub)
self->args[i].print_with_tree_printer(sub)

def free(self) -> None:
for i = 0; i < self->nargs; i++:
Expand All @@ -390,14 +393,18 @@ class AstInstantiation:
for i = 0; i < self->nfields; i++:
sub = tp.print_prefix(i == self->nfields - 1)
printf("field \"%s\": ", self->field_names[i])
self->field_values[i].print(sub)
self->field_values[i].print_with_tree_printer(sub)

def free(self) -> None:
for i = 0; i < self->nfields; i++:
self->field_values[i].free()
free(self->field_names)
free(self->field_values)

class AstAssertion:
condition: AstExpression
condition_str: byte*

enum AstStatementKind:
ExpressionStatement # Evaluate an expression. Discard the result.
Assert
Expand Down Expand Up @@ -436,21 +443,25 @@ class AstStatement:
function: AstFunctionOrMethod
classdef: AstClassDef
enumdef: AstEnumDef
assertion: AstAssertion

def print(self, tp: TreePrinter) -> None:
def print(self) -> None:
self->print_with_tree_printer(TreePrinter{})

def print_with_tree_printer(self, tp: TreePrinter) -> None:
printf("[line %d] ", self->location.lineno)
if self->kind == AstStatementKind::ExpressionStatement:
printf("expression statement\n")
self->expression.print(tp.print_prefix(True))
self->expression.print_with_tree_printer(tp.print_prefix(True))
elif self->kind == AstStatementKind::Assert:
printf("assert\n")
self->expression.print(tp.print_prefix(True))
printf("assert \"%s\"\n", self->assertion.condition_str)
self->assertion.condition.print_with_tree_printer(tp.print_prefix(True))
elif self->kind == AstStatementKind::Pass:
printf("pass\n")
elif self->kind == AstStatementKind::Return:
printf("return\n")
if self->return_value != NULL:
self->return_value->print(tp.print_prefix(True))
self->return_value->print_with_tree_printer(tp.print_prefix(True))
elif self->kind == AstStatementKind::If:
printf("if\n")
self->if_statement.print(tp)
Expand All @@ -459,51 +470,51 @@ class AstStatement:
self->for_loop.print(tp)
elif self->kind == AstStatementKind::WhileLoop:
printf("while loop\n")
self->while_loop.print(tp, True)
self->while_loop.print_with_tree_printer(tp, True)
elif self->kind == AstStatementKind::Break:
printf("break\n")
elif self->kind == AstStatementKind::Continue:
printf("continue\n")
elif self->kind == AstStatementKind::DeclareLocalVar:
printf("declare local var ")
self->var_declaration.print(&tp)
self->var_declaration.print_with_tree_printer(&tp)
elif self->kind == AstStatementKind::Assign:
printf("assign\n")
self->assignment.print(tp)
self->assignment.print_with_tree_printer(tp)
elif self->kind == AstStatementKind::InPlaceAdd:
printf("in-place add\n")
self->assignment.print(tp)
self->assignment.print_with_tree_printer(tp)
elif self->kind == AstStatementKind::InPlaceSubtract:
printf("in-place sub\n")
self->assignment.print(tp)
self->assignment.print_with_tree_printer(tp)
elif self->kind == AstStatementKind::InPlaceMultiply:
printf("in-place mul\n")
self->assignment.print(tp)
self->assignment.print_with_tree_printer(tp)
elif self->kind == AstStatementKind::InPlaceDivide:
printf("in-place div\n")
self->assignment.print(tp)
self->assignment.print_with_tree_printer(tp)
elif self->kind == AstStatementKind::InPlaceModulo:
printf("in-place mod\n")
self->assignment.print(tp)
self->assignment.print_with_tree_printer(tp)
elif self->kind == AstStatementKind::Function:
if self->function.body.nstatements == 0:
printf("declare a function: ")
else:
printf("define a function: ")
self->function.print(tp)
self->function.print_with_tree_printer(tp)
elif self->kind == AstStatementKind::Class:
printf("define a ")
self->classdef.print(tp)
self->classdef.print_with_tree_printer(tp)
elif self->kind == AstStatementKind::Enum:
printf("define ")
self->enumdef.print(tp)
self->enumdef.print_with_tree_printer(tp)
elif self->kind == AstStatementKind::GlobalVariableDeclaration:
printf("declare global var ")
self->var_declaration.print(NULL)
self->var_declaration.print_with_tree_printer(NULL)
printf("\n")
elif self->kind == AstStatementKind::GlobalVariableDefinition:
printf("define global var ")
self->var_declaration.print(NULL)
self->var_declaration.print_with_tree_printer(NULL)
printf("\n")
else:
printf("??????\n")
Expand All @@ -526,14 +537,17 @@ class AstConditionAndBody:
condition: AstExpression
body: AstBody

def print(self, tp: TreePrinter, body_is_last_sub_item: bool) -> None:
def print(self) -> None:
self->print_with_tree_printer(TreePrinter{}, True)

def print_with_tree_printer(self, tp: TreePrinter, body_is_last_sub_item: bool) -> None:
sub = tp.print_prefix(False)
printf("condition: ")
self->condition.print(sub)
self->condition.print_with_tree_printer(sub)

sub = tp.print_prefix(body_is_last_sub_item)
printf("body:\n")
self->body.print(sub)
self->body.print_with_tree_printer(sub)

def free(self) -> None:
self->condition.free()
Expand All @@ -543,9 +557,12 @@ class AstAssignment:
target: AstExpression
value: AstExpression

def print(self, tp: TreePrinter) -> None:
self->target.print(tp.print_prefix(False))
self->value.print(tp.print_prefix(True))
def print(self) -> None:
self->print_with_tree_printer(TreePrinter{})

def print_with_tree_printer(self, tp: TreePrinter) -> None:
self->target.print_with_tree_printer(tp.print_prefix(False))
self->value.print_with_tree_printer(tp.print_prefix(True))

class AstIfStatement:
if_and_elifs: AstConditionAndBody*
Expand All @@ -554,12 +571,12 @@ class AstIfStatement:

def print(self, tp: TreePrinter) -> None:
for i = 0; i < self->n_if_and_elifs; i++:
self->if_and_elifs[i].print(tp, i == self->n_if_and_elifs - 1 and self->else_body.nstatements == 0)
self->if_and_elifs[i].print_with_tree_printer(tp, i == self->n_if_and_elifs - 1 and self->else_body.nstatements == 0)

if self->else_body.nstatements > 0:
sub = tp.print_prefix(True)
printf("else body:\n")
self->else_body.print(sub)
self->else_body.print_with_tree_printer(sub)

def free(self) -> None:
for i = 0; i < self->n_if_and_elifs; i++:
Expand All @@ -580,19 +597,19 @@ class AstForLoop:
def print(self, tp: TreePrinter) -> None:
sub = tp.print_prefix(False)
printf("init: ")
self->init->print(sub)
self->init->print_with_tree_printer(sub)

sub = tp.print_prefix(False)
printf("cond: ")
self->cond.print(sub)
self->cond.print_with_tree_printer(sub)

sub = tp.print_prefix(False)
printf("incr: ")
self->incr->print(sub)
self->incr->print_with_tree_printer(sub)

sub = tp.print_prefix(True)
printf("body:\n")
self->body.print(sub)
self->body.print_with_tree_printer(sub)

def free(self) -> None:
self->init->free()
Expand All @@ -609,8 +626,12 @@ class AstNameTypeValue:
type: AstType
value: AstExpression* # can be NULL

def print(self) -> None:
tp = TreePrinter{}
self->print_with_tree_printer(&tp)

# tp can be set to NULL, in that case no trailing newline is printed
def print(self, tp: TreePrinter*) -> None:
def print_with_tree_printer(self, tp: TreePrinter*) -> None:
printf("%s: ", self->name)
self->type.print(True)
if tp == NULL:
Expand All @@ -620,7 +641,7 @@ class AstNameTypeValue:
if self->value != NULL:
sub = tp->print_prefix(True)
printf("initial value: ")
self->value->print(sub)
self->value->print_with_tree_printer(sub)

def free(self) -> None:
if self->value != NULL:
Expand All @@ -631,9 +652,12 @@ class AstBody:
statements: AstStatement*
nstatements: int

def print(self, tp: TreePrinter) -> None:
def print(self) -> None:
self->print_with_tree_printer(TreePrinter{})

def print_with_tree_printer(self, tp: TreePrinter) -> None:
for i = 0; i < self->nstatements; i++:
self->statements[i].print(tp.print_prefix(i == self->nstatements - 1))
self->statements[i].print_with_tree_printer(tp.print_prefix(i == self->nstatements - 1))

def free(self) -> None:
for i = 0; i < self->nstatements; i++:
Expand All @@ -656,7 +680,7 @@ class AstSignature:
if strcmp(self->args[i].name, "self") == 0:
printf("self")
else:
self->args[i].print(NULL)
self->args[i].print_with_tree_printer(NULL)

if self->takes_varargs:
if self->nargs != 0:
Expand Down Expand Up @@ -695,7 +719,7 @@ class AstFile:
for i = 0; i < self->nimports; i++:
self->imports[i].print()
for i = 0; i < self->body.nstatements; i++:
self->body.statements[i].print(TreePrinter{})
self->body.statements[i].print()

def free(self) -> None:
for i = 0; i < self->nimports; i++:
Expand All @@ -707,9 +731,12 @@ class AstFunctionOrMethod:
signature: AstSignature
body: AstBody # empty body means declaration, otherwise it's a definition

def print(self, tp: TreePrinter) -> None:
def print(self) -> None:
self->print_with_tree_printer(TreePrinter{})

def print_with_tree_printer(self, tp: TreePrinter) -> None:
self->signature.print()
self->body.print(tp)
self->body.print_with_tree_printer(tp)

def free(self) -> None:
self->signature.free()
Expand All @@ -722,7 +749,7 @@ class AstUnionFields:
def print(self, tp: TreePrinter) -> None:
for i = 0; i < self->nfields; i++:
subprinter = tp.print_prefix(i == self->nfields-1)
self->fields[i].print(&subprinter) # TODO: does this need to be optional/pointer?
self->fields[i].print_with_tree_printer(&subprinter) # TODO: does this need to be optional/pointer?

def free(self) -> None:
for i = 0; i < self->nfields; i++:
Expand All @@ -744,15 +771,15 @@ class AstClassMember:
def print(self, tp: TreePrinter) -> None:
if self->kind == AstClassMemberKind::Field:
printf("field ")
self->field.print(NULL)
self->field.print_with_tree_printer(NULL)
printf("\n")
elif self->kind == AstClassMemberKind::Union:
printf("union:\n")
self->union_fields.print(tp)
elif self->kind == AstClassMemberKind::Method:
printf("method ")
self->method.signature.print()
self->method.body.print(tp)
self->method.body.print_with_tree_printer(tp)
else:
assert False

Expand All @@ -772,7 +799,10 @@ class AstClassDef:
members: AstClassMember*
nmembers: int

def print(self, tp: TreePrinter) -> None:
def print(self) -> None:
self->print_with_tree_printer(TreePrinter{})

def print_with_tree_printer(self, tp: TreePrinter) -> None:
printf("class \"%s\" with %d members\n", self->name, self->nmembers)
for i = 0; i < self->nmembers; i++:
self->members[i].print(tp.print_prefix(i == self->nmembers-1))
Expand All @@ -788,7 +818,10 @@ class AstEnumDef:
member_count: int
member_names: byte[100]*

def print(self, tp: TreePrinter) -> None:
def print(self) -> None:
self->print_with_tree_printer(TreePrinter{})

def print_with_tree_printer(self, tp: TreePrinter) -> None:
printf("enum \"%s\" with %d members\n", self->name, self->member_count)
for i = 0; i < self->member_count; i++:
tp.print_prefix(i == self->member_count-1)
Expand Down
Loading

0 comments on commit fae5e3d

Please sign in to comment.