Skip to content

Commit

Permalink
Make classes private by default (#759)
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli authored Feb 8, 2025
1 parent f0c3258 commit 7c72409
Show file tree
Hide file tree
Showing 23 changed files with 126 additions and 15 deletions.
29 changes: 29 additions & 0 deletions compiler/ast.jou
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ enum AstTypeKind:
Array


@public
class AstArrayType:
member_type: AstType*
length: AstExpression*
Expand All @@ -33,6 +34,7 @@ class AstArrayType:
free(self->length)


@public
class AstType:
kind: AstTypeKind
location: Location
Expand Down Expand Up @@ -97,12 +99,14 @@ class TreePrinter:


# Foo.Bar where Foo is an enum
@public
class AstEnumMember:
enum_name: byte[100]
member_name: byte[100]


# foo.bar, foo->bar
@public
class AstClassField:
instance: AstExpression*
uses_arrow_operator: bool # distinguishes foo.bar and foo->bar
Expand All @@ -114,6 +118,7 @@ class AstClassField:


# Foo{bar = 1, baz = 2}
@public
class AstInstantiation:
class_name_location: Location # TODO: probably not necessary, can use location of the instantiate expression
class_name: byte[100]
Expand Down Expand Up @@ -183,6 +188,7 @@ enum AstExpressionKind:
And # x and y
Or # x or y

@public
class AstExpression:
location: Location
kind: AstExpressionKind
Expand Down Expand Up @@ -382,6 +388,7 @@ class AstExpression:


# [foo, bar, baz]
@public
class AstArray:
length: int
items: AstExpression*
Expand All @@ -393,6 +400,7 @@ class AstArray:


# foo as bar
@public
class AstAs:
value: AstExpression
type: AstType
Expand All @@ -414,6 +422,7 @@ class AstAs:
# foo(arg1, arg2, arg3)
# foo.bar(arg1, arg2, arg3)
# foo->bar(arg1, arg2, arg3)
@public
class AstCall:
location: Location
name: byte[100] # name of function or method
Expand Down Expand Up @@ -459,6 +468,7 @@ class AstCall:


# assert foo
@public
class AstAssertion:
condition: AstExpression
condition_str: byte*
Expand Down Expand Up @@ -498,6 +508,7 @@ enum AstStatementKind:
GlobalVariableDeclare
GlobalVariableDef

@public
class AstStatement:
location: Location
kind: AstStatementKind
Expand Down Expand Up @@ -657,6 +668,7 @@ class AstStatement:


# Useful for e.g. "while condition: body", "if condition: body"
@public
class AstConditionAndBody:
condition: AstExpression
body: AstBody
Expand All @@ -679,6 +691,7 @@ class AstConditionAndBody:


# foo = bar
@public
class AstAssignment:
target: AstExpression
value: AstExpression
Expand All @@ -703,6 +716,7 @@ class AstAssignment:
# ...
# else:
# ...
@public
class AstIfStatement:
if_and_elifs: AstConditionAndBody*
n_if_and_elifs: int # At least 1 (the if statement). The rest, if any, are elifs.
Expand Down Expand Up @@ -733,6 +747,7 @@ class AstIfStatement:
# ...
# case ...:
# ...
@public
class AstMatchStatement:
match_obj: AstExpression
func_name: byte[100] # empty if there's no "with foo"
Expand Down Expand Up @@ -766,6 +781,7 @@ class AstMatchStatement:

# case case_obj1 | case_obj2 | case_obj3:
# body
@public
class AstCase:
case_objs: AstExpression*
n_case_objs: int
Expand All @@ -790,6 +806,7 @@ class AstCase:

# for init; cond; incr:
# ...body...
@public
class AstForLoop:
init: AstStatement* # may be NULL
cond: AstExpression* # may be NULL
Expand Down Expand Up @@ -835,6 +852,7 @@ class AstForLoop:


# name: type = value
@public
class AstNameTypeValue:
name: byte[100]
name_location: Location
Expand Down Expand Up @@ -883,6 +901,7 @@ class AstGlobalVarDeclare:

# global foo: int
# TODO: support specifying an initial value
@public
class AstGlobalVarDef:
name: byte[100]
type: AstType
Expand All @@ -899,6 +918,7 @@ class AstGlobalVarDef:


# typically multiple indented lines after a ":" at end of line
@public
class AstBody:
statements: AstStatement*
nstatements: int
Expand All @@ -917,6 +937,7 @@ class AstBody:


# function name and parameters in "def" or "declare"
@public
class AstSignature:
name_location: Location
name: byte[100] # name of function or method, after "def" keyword
Expand Down Expand Up @@ -958,6 +979,7 @@ class AstSignature:


# import "./foo.jou"
@public
class AstImport:
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"
Expand All @@ -975,6 +997,7 @@ class AstImport:


# Represents the AST of one Jou file.
@public
class AstFile:
path: byte* # not owned
is_main_file: bool # is this the file passed in Jou compiler command? False means imported file
Expand All @@ -993,6 +1016,7 @@ class AstFile:

# def foo() -> bar:
# ...
@public
class AstFunctionOrMethod:
ast_signature: AstSignature
body: AstBody
Expand All @@ -1018,6 +1042,7 @@ class AstFunctionOrMethod:
# union:
# foo: type1
# bar: type2
@public
class AstUnionFields:
fields: AstNameTypeValue*
nfields: int
Expand All @@ -1038,10 +1063,13 @@ class AstUnionFields:

# class Foo:
# ...members...
@public
class AstClassDef:
name: byte[100]
body: AstBody*
type: Type* # populated in typecheck, NULL before typecheck runs
public: bool # is it decorated with @public
used: bool # used to detect unused classes

def print(self) -> None:
self->print_with_tree_printer(TreePrinter{})
Expand All @@ -1059,6 +1087,7 @@ class AstClassDef:
# Member1
# Member2
# Member3
@public
class AstEnumDef:
name: byte[100]
name_location: Location
Expand Down
3 changes: 3 additions & 0 deletions compiler/builders/either_builder.jou
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@ import "./llvm_builder.jou"
import "./uvg_builder.jou"


@public
class EitherBuilderValue:
lvalue: LBuilderValue
uvalue: int


@public
class EitherBuilderBlock:
lblock: LLVMBasicBlock*
ublock: UvgBlock* # funny naming :)


@public
class EitherBuilder:
lbuilder: LBuilder* # may be NULL
ubuilder: UBuilder* # may be NULL
Expand Down
2 changes: 2 additions & 0 deletions compiler/builders/llvm_builder.jou
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,14 @@ def find_enum_member(enumtype: Type*, name: byte*) -> int:
assert False


@public
class LBuilderValue:
type: Type*
llvm_value: LLVMValue*


# Not named LLVMBuilder because that is the name of LLVM's thing.
@public
class LBuilder:
llvm_module: LLVMModule*
llvm_builder: LLVMBuilder*
Expand Down
1 change: 1 addition & 0 deletions compiler/builders/uvg_builder.jou
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def FALSE_ID() -> int:
return -3


@public
class UBuilder:
uvg: Uvg
current_block: UvgBlock*
Expand Down
1 change: 1 addition & 0 deletions compiler/errors_and_warnings.jou
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "stdlib/process.jou"
import "stdlib/io.jou"

@public
class Location:
path: byte* # Not owned. Points to a string that is held elsewhere.
lineno: int
Expand Down
8 changes: 8 additions & 0 deletions compiler/llvm.jou
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
@public
class LLVMModule:
_dummy: int
@public
class LLVMType:
_dummy: int
@public
class LLVMValue:
_dummy: int
@public
class LLVMBasicBlock:
_dummy: int
@public
class LLVMBuilder:
_dummy: int
class LLVMPassManager:
_dummy: int

@public
class LLVMTarget:
_dummy: int
@public
class LLVMTargetData:
_dummy: int
@public
class LLVMTargetMachine:
_dummy: int

Expand Down
4 changes: 4 additions & 0 deletions compiler/main.jou
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ class FileState:
if not stmt->global_var_declare.public and not stmt->global_var_declare.used:
snprintf(msg, sizeof msg, "global variable '%s' declared but not used", stmt->global_var_declare.name)
show_warning(stmt->location, msg)
case AstStatementKind.Class:
if not stmt->classdef.public and not stmt->classdef.used:
snprintf(msg, sizeof msg, "class '%s' defined but not used", stmt->classdef.name)
show_warning(stmt->location, msg)
case _:
pass

Expand Down
8 changes: 4 additions & 4 deletions compiler/parser.jou
Original file line number Diff line number Diff line change
Expand Up @@ -145,16 +145,16 @@ def decorate(stmt: AstStatement*, decor: byte*, location: Location) -> None:
if strcmp(stmt->function.ast_signature.name, "main") == 0:
fail(location, "the main() function cannot be @public")
stmt->function.public = True
case AstStatementKind.MethodDef:
fail(location, "methods cannot be decorated with @public, a class is either fully public or fully private")
case AstStatementKind.Class:
stmt->classdef.public = True
case AstStatementKind.Enum:
stmt->enumdef.public = True
case AstStatementKind.GlobalVariableDeclare:
stmt->global_var_declare.public = True
case AstStatementKind.GlobalVariableDef:
stmt->global_var_def.public = True
# Temporarily allow and ignore using @public on enums, classes and global variables.
# This is needed for the bootstrap compiler to accept new syntax.
case AstStatementKind.Class:
pass # TODO: handle these cases properly
case _:
fail(location, "the @public decorator cannot be used here")
else:
Expand Down
1 change: 1 addition & 0 deletions compiler/token.jou
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ enum TokenKind:
Operator
EndOfFile # Marks the end of an array of tokens.

@public
class Token:
kind: TokenKind
location: Location
Expand Down
1 change: 1 addition & 0 deletions compiler/typecheck/common.jou
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum ExportSymbolKind:
Type
GlobalVar

@public
class ExportSymbol:
kind: ExportSymbolKind
name: byte[100] # TODO: maybe this should be 200 because it can be ClassName.method_name? or something else?
Expand Down
4 changes: 2 additions & 2 deletions compiler/typecheck/step1_create_types.jou
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ def typecheck_step1_create_types(ast: AstFile*) -> ExportSymbol*:
match stmt->kind:
case AstStatementKind.Class:
name = stmt->classdef.name
public = True
usedptr = NULL
public = stmt->classdef.public
usedptr = &stmt->classdef.used
t = create_opaque_class(name)
stmt->classdef.type = t
case AstStatementKind.Enum:
Expand Down
3 changes: 3 additions & 0 deletions compiler/types.jou
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import "stdlib/str.jou"

import "./errors_and_warnings.jou"

@public
class ClassField:
name: byte[100]
type: Type*
Expand Down Expand Up @@ -37,6 +38,7 @@ enum TypeKind:
OpaqueClass # class with unknown members, used temporarily during type checking
Enum

@public
class Type:
name: byte[500] # All types have a name for error messages and debugging.
kind: TypeKind
Expand Down Expand Up @@ -283,6 +285,7 @@ def create_enum(name: byte*, membercount: int, membernames: byte[100]*) -> Type*
return &result->type


@public
class Signature:
name: byte[100] # Function or method name. For methods it does not include the name of the class.
nargs: int
Expand Down
Loading

0 comments on commit 7c72409

Please sign in to comment.