Skip to content

Commit

Permalink
Port the whole Jou compiler to Jou (#562)
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli authored Jan 8, 2025
1 parent 04c1599 commit 5b48fac
Show file tree
Hide file tree
Showing 35 changed files with 10,246 additions and 1,971 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/netbsd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ jobs:
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: cross-platform-actions/[email protected]
# TODO: disabled for now because freezes with no output for some reason.
# Started happening in #562, so it has something to do with self-hosted compiler.
- if: false
uses: cross-platform-actions/[email protected]
env:
PKG_PATH: 'https://cdn.NetBSD.org/pub/pkgsrc/packages/NetBSD/amd64/10.0/All'
with:
Expand Down
18 changes: 11 additions & 7 deletions compare_compilers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,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
# skip compiler_cli, because it hard-codes name of compiler executable
# TODO: do not skip Advent Of Code files
files=( $(find stdlib examples tests -name '*.jou' | grep -v aoc202. | grep -v tests/should_succeed/compiler_cli | grep -v tests/crash | sort) )
files=( $(find stdlib examples tests -name '*.jou' | grep -v aoc202. | grep -v tests/should_succeed/compiler_cli | grep -v tests/crash | grep -v x11_window | sort) )
fi
if [ ${#actions[@]} = 0 ]; then
actions=(tokenize parse run)
Expand Down Expand Up @@ -108,17 +108,21 @@ for action in ${actions[@]}; do
flag=--${action}-only
fi

# Run both compilers, and filter out lines that are known to differ but it doesn't matter (mostly linker errors)
# Run compilers in parallel to speed up.
# Run both compilers, and filter out lines that are known to differ but it doesn't
# matter (mostly linker errors).
#
# It is tempting to run compilers in parallel to speed up, but it doesn't work
# because they use the same temporary files in jou_compiled directories.
(
set +e
./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 &
true
) > 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|compiler warning for file'
) > tmp/compare_compilers/self_hosted.txt &
wait
true
) > tmp/compare_compilers/self_hosted.txt

if [ -f $error_list_file ] && grep -qxF $file <(cat $error_list_file | tr -d '\r'); then
# The file is skipped, so the two compilers should behave differently
Expand Down
27 changes: 20 additions & 7 deletions self_hosted/ast.jou
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class AstArrayType:
member_type: AstType*
length: AstExpression*

# TODO: use this
def free(self) -> None:
self->member_type->free()
self->length->free()
Expand All @@ -30,15 +31,19 @@ class AstType:
value_type: AstType* # AstTypeKind::Pointer
array: AstArrayType # AstTypeKind::Array

# TODO: use this
def is_void(self) -> bool:
return self->kind == AstTypeKind::Named and strcmp(self->name, "void") == 0

# TODO: use this
def is_none(self) -> bool:
return self->kind == AstTypeKind::Named and strcmp(self->name, "None") == 0

# TODO: use this
def is_noreturn(self) -> bool:
return self->kind == AstTypeKind::Named and strcmp(self->name, "noreturn") == 0

# TODO: use this
def print(self, show_lineno: bool) -> None:
if self->kind == AstTypeKind::Named:
printf("%s", self->name)
Expand All @@ -54,6 +59,7 @@ class AstType:
if show_lineno:
printf(" [line %d]", self->location.lineno)

# TODO: use this
def free(self) -> None:
if self->kind == AstTypeKind::Pointer:
self->value_type->free()
Expand Down Expand Up @@ -96,7 +102,7 @@ enum AstExpressionKind:
Self # not a variable lookup, so you can't use 'self' as variable name outside a class
GetVariable
GetEnumMember
GetClassField
GetClassField # foo.bar, foo->bar
As
# unary operators
SizeOf # sizeof x
Expand Down Expand Up @@ -139,15 +145,17 @@ class AstExpression:
bool_value: bool
call: AstCall
instantiation: AstInstantiation
as_expression: AstAsExpression* # Must be pointer, because it contains an AstExpression
as_: AstAsExpression* # Must be pointer, because it contains an AstExpression
array: AstArray
varname: byte[100]
float_or_double_text: byte[100]
operands: AstExpression* # Only for operators. Length is arity, see get_arity()

# TODO: use this
def print(self) -> None:
self->print_with_tree_printer(TreePrinter{})

# TODO: use this
def print_with_tree_printer(self, tp: TreePrinter) -> None:
printf("[line %d] ", self->location.lineno)
if self->kind == AstExpressionKind::String:
Expand Down Expand Up @@ -210,9 +218,9 @@ class AstExpression:
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)
self->as_->type.print(True)
printf("\n")
self->as_expression->value.print_with_tree_printer(tp.print_prefix(True))
self->as_->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 @@ -263,12 +271,13 @@ class AstExpression:
for i = 0; i < self->get_arity(); i++:
self->operands[i].print_with_tree_printer(tp.print_prefix(i == self->get_arity()-1))

# TODO: use this
def free(self) -> None:
if self->kind == AstExpressionKind::Call:
self->call.free()
elif self->kind == AstExpressionKind::As:
self->as_expression->free()
free(self->as_expression)
self->as_->free()
free(self->as_)
elif self->kind == AstExpressionKind::String:
free(self->string)
elif self->kind == AstExpressionKind::GetClassField:
Expand All @@ -279,6 +288,7 @@ class AstExpression:
self->operands[i].free()
free(self->operands)

# TODO: use this
# arity = number of operands, e.g. 2 for a binary operator such as "+"
def get_arity(self) -> int:
if (
Expand Down Expand Up @@ -312,6 +322,7 @@ class AstExpression:
return 2
return 0

# TODO: use this
def can_have_side_effects(self) -> bool:
return (
self->kind == AstExpressionKind::Call
Expand All @@ -325,6 +336,7 @@ class AstArray:
length: int
items: AstExpression*

# TODO: use this
def free(self) -> None:
for i = 0; i < self->length; i++:
self->items[i].free()
Expand Down Expand Up @@ -383,7 +395,7 @@ class AstCall:
free(self->args)

class AstInstantiation:
class_name_location: Location
class_name_location: Location # TODO: probably not necessary, can use location of the instantiate expression
class_name: byte[100]
nfields: int
field_names: byte[100]*
Expand Down Expand Up @@ -704,6 +716,7 @@ class AstImport:
location: Location
specified_path: byte* # Path in jou code e.g. "stdlib/io.jou"
resolved_path: byte* # Absolute path or relative to current working directory e.g. "/home/akuli/jou/stdlib/io.jou"
used: bool # For warning messages

def print(self) -> None:
printf(
Expand Down
Loading

0 comments on commit 5b48fac

Please sign in to comment.