Skip to content

Commit

Permalink
Merge branch 'master' into reflection
Browse files Browse the repository at this point in the history
  • Loading branch information
Victorious3 committed May 17, 2024
2 parents 3020717 + b714f0e commit 6885b34
Show file tree
Hide file tree
Showing 17 changed files with 618 additions and 588 deletions.
6 changes: 3 additions & 3 deletions src/codegen.pr
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import builtins
def type_to_str(tpe: &typechecking::Type) -> Str {
if not tpe { return "void" }
if tpe.kind == typechecking::TypeKind::BOX {
tpe = tpe.weak
tpe = tpe.wk
}
var ret: StringBuffer = ""
switch tpe.kind !int {
Expand All @@ -30,7 +30,7 @@ def type_to_str(tpe: &typechecking::Type) -> Str {
case 16; ret = "x86_fp80"
case; assert
}
case typechecking::TypeKind::POINTER
case typechecking::TypeKind::POINTER, typechecking::TypeKind::BYREF
if tpe.tpe and tpe.tpe.kind != typechecking::TypeKind::STRUCTURAL {
ret = type_to_str(tpe.tpe)
ret += '*'
Expand All @@ -39,7 +39,7 @@ def type_to_str(tpe: &typechecking::Type) -> Str {
ret = "i8*"
}
case typechecking::TypeKind::REFERENCE, typechecking::TypeKind::WEAK_REF
ret = "{i64*, "
ret = "{{i64, i64}*, "
if tpe.tpe and tpe.tpe.kind != typechecking::TypeKind::STRUCTURAL {
ret += type_to_str(tpe.tpe)
ret += '*'
Expand Down
741 changes: 353 additions & 388 deletions src/compiler.pr

Large diffs are not rendered by default.

11 changes: 7 additions & 4 deletions src/consteval.pr
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,9 @@ export def walk_Def(node: &parser::Node, state: &typechecking::State) {
tpe.type_name = tpe.name = scope::last_path_element(param.value.param.name)
} else {
tpe = typechecking::type_lookup(param.value.param.tpe, state, null, true)
if param.value.param.is_ref {
tpe = typechecking::byref(tpe)
}
}

var value: &compiler::Value
Expand Down Expand Up @@ -411,7 +414,7 @@ export def walk_Def(node: &parser::Node, state: &typechecking::State) {
is_closure = node.parent.kind != parser::NodeKind::PROGRAM,
scope = state.scope,
inner_scope = node.inner_scope,
captures = vector::make(type weak_ref(scope::Value)),
captures = vector::make(type weak &scope::Value),
dllimport = dllimport,
dllexport = dllexport or test,
test = test,
Expand Down Expand Up @@ -444,10 +447,10 @@ export def walk_Def(node: &parser::Node, state: &typechecking::State) {
let type_constructor = typechecking::get_type_constructor(first_param.tpe)
if type_constructor and type_constructor.cache {
let type_name = debug::type_to_str(first_param.tpe, full_name = true)
let ref = [module = state.get_context(), name = type_name] !typechecking::TypeRef
if not map::contains(type_constructor.cache, ref) {
let _ref = [module = state.get_context(), name = type_name] !typechecking::TypeRef
if not map::contains(type_constructor.cache, _ref) {
typechecking::generate_concrete_functions(type_constructor, first_param.tpe, state)
type_constructor.cache(ref) = first_param.tpe
type_constructor.cache(_ref) = first_param.tpe
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/debug.pr
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@ export def type_to_str(tpe: &typechecking::Type, full_name: bool = false) -> Str
if tpe.tc_tpe { return tc_args_to_string(tpe, full_name) }
switch tpe.kind !int {
case typechecking::TypeKind::BOX
return "Box<" + type_to_str(tpe.weak, full_name) + ">"
return "Box<" + type_to_str(tpe.wk, full_name) + ">"
case typechecking::TypeKind::VOID
return "void"
case typechecking::TypeKind::BOOL
Expand All @@ -862,7 +862,7 @@ export def type_to_str(tpe: &typechecking::Type, full_name: bool = false) -> Str
return function_t_to_string(tpe, full_name)
case typechecking::TypeKind::TUPLE
return tuple_t_to_string(tpe, full_name)
case typechecking::TypeKind::POINTER
case typechecking::TypeKind::POINTER, typechecking::TypeKind::BYREF
return pointer_t_to_string(tpe, full_name)
case typechecking::TypeKind::REFERENCE
return reference_t_to_string(tpe, full_name)
Expand Down
10 changes: 5 additions & 5 deletions src/eval.pr
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,11 @@ export def get(mem: *, tpe: &typechecking::Type) -> compiler::Value {
return [ kind = compiler::ValueKind::FLOAT, tpe = tpe, f = result ] !compiler::Value
case typechecking::TypeKind::BOOL
return [ kind = compiler::ValueKind::BOOL, tpe = tpe, i = (@(mem !*bool)) !int64 ] !compiler::Value
case typechecking::TypeKind::POINTER
case typechecking::TypeKind::POINTER, typechecking::TypeKind::BYREF
return [ kind = compiler::ValueKind::POINTER, tpe = tpe, i = @(mem !*int64) ] !compiler::Value
case typechecking::TypeKind::REFERENCE, typechecking::TypeKind::WEAK_REF
let values = allocate_ref(compiler::Value, 3)
values(0) = [ kind = compiler::ValueKind::POINTER, tpe = typechecking::pointer(builtins::size_t_), i = @(mem !*int64) ] !compiler::Value
values(0) = [ kind = compiler::ValueKind::POINTER, tpe = typechecking::pointer(compiler::ref_meta()), i = @(mem !*int64) ] !compiler::Value
values(1) = [ kind = compiler::ValueKind::POINTER, tpe = typechecking::pointer(tpe.tpe), i = @((mem ++ (size_of type *)) !*int64) ] !compiler::Value
values(2) = [ kind = compiler::ValueKind::POINTER, tpe = typechecking::pointer(builtins::Type_), i = @((mem ++ (size_of type *) * 2) !*int64) ] !compiler::Value
return [ kind = compiler::ValueKind::STRUCT, tpe = tpe, values = values ] !compiler::Value
Expand Down Expand Up @@ -271,7 +271,7 @@ def set(mem: *, tpe: &typechecking::Type, value: compiler::Value) {
} else {
assert(false)
}
case typechecking::TypeKind::POINTER
case typechecking::TypeKind::POINTER, typechecking::TypeKind::BYREF
(@(mem !*int64)) = value.i
case typechecking::TypeKind::REFERENCE, typechecking::TypeKind::WEAK_REF
@(mem !*int64) = value.values(0).i
Expand Down Expand Up @@ -364,7 +364,7 @@ def unwrap_undef(value: compiler::Value) -> compiler::Value {
value = [ kind = compiler::ValueKind::ARRAY, tpe = value.tpe, values = values ] !compiler::Value
} else if value.tpe.kind == typechecking::TypeKind::REFERENCE or value.tpe.kind == typechecking::TypeKind::WEAK_REF {
let values = allocate_ref(compiler::Value, 3)
values(0) = [ kind = compiler::ValueKind::UNDEF, tpe = typechecking::pointer(builtins::size_t_) ] !compiler::Value
values(0) = [ kind = compiler::ValueKind::UNDEF, tpe = typechecking::pointer(compiler::ref_meta()) ] !compiler::Value
values(1) = [ kind = compiler::ValueKind::UNDEF, tpe = typechecking::pointer(value.tpe.tpe) ] !compiler::Value
values(2) = [ kind = compiler::ValueKind::UNDEF, tpe = typechecking::pointer(builtins::Type_) ] !compiler::Value
value = [ kind = compiler::ValueKind::STRUCT, tpe = value.tpe, values = values ] !compiler::Value
Expand Down Expand Up @@ -469,7 +469,7 @@ def eval_GetElementPtr(insn: &compiler::Insn, state: &State) {
}
} else if tpe.kind == typechecking::TypeKind::REFERENCE {
if index == 0 {
tpe = typechecking::pointer(builtins::size_t_)
tpe = typechecking::pointer(compiler::ref_meta())
} else if index == 1 {
addr = addr ++ (size_of type *)
tpe = tpe.tpe
Expand Down
8 changes: 5 additions & 3 deletions src/lexer.pr
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ export type TokenType = enum {
K_ASSERT
K_TYPE_OF
K_UNDEF
K_WEAK_REF
K_REF
K_WEAK
INTEGER
FLOAT
STRING
Expand Down Expand Up @@ -223,9 +224,10 @@ let KEYWORDS = [
[token_type = TokenType::K_DEFINED, str = "defined"] !Keyword,
[token_type = TokenType::K_DEFER, str = "defer"] !Keyword,
[token_type = TokenType::K_TYPE_OF, str = "type_of"] !Keyword,
[token_type = TokenType::K_WEAK_REF, str = "weak_ref"] !Keyword,
[token_type = TokenType::K_WEAK, str = "weak"] !Keyword,
[token_type = TokenType::K_YIELD, str = "yield"] !Keyword,
[token_type = TokenType::K_IMPLICIT, str = "implicit"] !Keyword
[token_type = TokenType::K_IMPLICIT, str = "implicit"] !Keyword,
[token_type = TokenType::K_REF, str = "ref"] !Keyword
]

export def token_list_to_json(list: *TokenList) -> &Json {
Expand Down
55 changes: 19 additions & 36 deletions src/parser.pr
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ export type NodeParam = struct {
name: &Node
tpe: &Node
value: &Node
is_ref: bool
}

export type NodeImportModule = struct {
Expand Down Expand Up @@ -464,7 +465,7 @@ export type Node = struct {
// For things like if statements or functions
inner_scope: &scope::Scope
value: NodeValue
parent: weak_ref(Node)
parent: weak &Node

// Set to prevent destructors being called on uninitalized values
is_initializer: bool
Expand All @@ -474,7 +475,7 @@ export type Node = struct {
body: &Vector(&Node)
// This is used by assignment to track let
kw: VarDecl
module: weak_ref(toolchain::Module)
module: weak &toolchain::Module
is_recursive_type: bool

// Need to keep copied type nodes in the tree
Expand Down Expand Up @@ -1855,51 +1856,25 @@ def expect_array_or_tuple(parse_state: &ParseState) -> &Node {
}

def expect_weak_ref(parse_state: &ParseState, inline_types: bool) -> &Node {
var tok = expect(parse_state, lexer::TokenType::K_WEAK_REF, "Expected weak_ref")
var tok = expect(parse_state, lexer::TokenType::K_WEAK, "Expected weak")

let line = tok.line
let column = tok.column

var tpe: &Node = null
var kw = VarDecl::VAR
tok = peek(parse_state)
if tok.tpe == lexer::TokenType::O_PAREN {
pop(parse_state)
skip_newline(parse_state)
tok = peek(parse_state)
if tok.tpe == lexer::TokenType::K_VAR {
pop(parse_state)
skip_newline(parse_state)
} else if tok.tpe == lexer::TokenType::K_LET {
pop(parse_state)
kw = VarDecl::LET
skip_newline(parse_state)
}

var tokens = parse_state.tokens
tpe = parse_type(parse_state, inline_types)
if not tpe {
parse_state.tokens = tokens
}

skip_newline(parse_state)
expect(parse_state, lexer::TokenType::C_PAREN, "Expected ')'")
}
let tpe = expect_type(parse_state)

var node = make_node(NodeKind::WEAK_REF_T, line, column, parse_state)
node.value.t_parr = [
kw = kw,
tpe = tpe
] !NodePtrArrayT
node._hash = combine_hashes(node.kind !uint64, kw !uint64, hash(tpe))
node._hash = combine_hashes(node.kind !uint64, hash(tpe))

return node
}

def expect_ptr_ref(parse_state: &ParseState, ref: bool, inline_types: bool) -> &Node {
def expect_ptr_ref(parse_state: &ParseState, _ref: bool, inline_types: bool) -> &Node {
var kind: NodeKind
var tok: lexer::Token
if ref {
if _ref {
kind = NodeKind::REF_T
tok = expect(parse_state, lexer::TokenType::OP_BAND, "Expected '&'")
} else {
Expand Down Expand Up @@ -2413,7 +2388,7 @@ def parse_type2(parse_state: &ParseState, inline_types: bool) -> &Node {
tok.tpe == lexer::TokenType::OP_BAND {
back(parse_state)
return expect_ptr_ref(parse_state, tok.tpe == lexer::TokenType::OP_BAND, inline_types)
} else if tok.tpe == lexer::TokenType::K_WEAK_REF {
} else if tok.tpe == lexer::TokenType::K_WEAK {
back(parse_state)
return expect_weak_ref(parse_state, inline_types)
} else if tok.tpe == lexer::TokenType::DOUBLE_COLON or
Expand Down Expand Up @@ -3368,6 +3343,13 @@ def parse_def(parse_state: &ParseState, share: ShareMarker, impl: bool = false)
var name: &Node = null
var tpe: &Node = null
var value: &Node = null
var is_ref = false

if token.tpe == lexer::TokenType::K_REF {
pop(parse_state)
is_ref = true
token = peek(parse_state)
}

if token.tpe == lexer::TokenType::OP_VARARGS {
if varargs {
Expand Down Expand Up @@ -3429,9 +3411,10 @@ def parse_def(parse_state: &ParseState, share: ShareMarker, impl: bool = false)
kw = kw,
name = name,
tpe = tpe,
value = value
value = value,
is_ref = is_ref
] !NodeParam
param._hash = combine_hashes(param.kind !uint64, varargs !uint64, kw !uint64, hash(name), hash(tpe), hash(value))
param._hash = combine_hashes(param.kind !uint64, varargs !uint64, kw !uint64, is_ref !uint64, hash(name), hash(tpe), hash(value))

params.push(param)

Expand Down
2 changes: 1 addition & 1 deletion src/repl.pr
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ def execute(source: Str) {

stack_frame = eval::make_stack_frame(main_function.block, "main", 1)

let mem = allocate(size_of type *) !**
let mem = allocate(16) !** // FIXME What are we doing here???
@mem = (*_args) !*
stack_frame.locals("args.value") = mem

Expand Down
7 changes: 6 additions & 1 deletion src/runtime.pr
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,13 @@ export type Field = struct {
tpe: *Type
}

export type Refcount = struct {
strong_cnt: int64
weak_cnt: int64
}

export type Ref = struct {
ref_count: *int64
ref_count: *Refcount
value: *
tpe: *Type
}
Expand Down
22 changes: 11 additions & 11 deletions src/scope.pr
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ export type Ident = struct {
name: Str
signature: Str
_hash: uint64
module: weak_ref(toolchain::Module)
module: weak &toolchain::Module
}

export type ImportedModule = struct {
module: weak_ref(toolchain::Module)
module: weak &toolchain::Module
alias: &parser::Node
}

Expand Down Expand Up @@ -72,7 +72,7 @@ export def find(ident: Ident) -> &Value {

export type Value = struct {
// This is needed to store the location
name_node: weak_ref(parser::Node)
name_node: weak &parser::Node
share: parser::ShareMarker
modifier: parser::VarDecl
// Name used by the source code
Expand All @@ -85,7 +85,7 @@ export type Value = struct {
tpe: &typechecking::Type
value: &compiler::Value
_scope: &Scope
_module: weak_ref(Scope) // This is needed for modules referencing each other
_module: weak &Scope // This is needed for modules referencing each other
// In case multiple values share one name (overloaded functions)
next: &Value
phase: Phase
Expand All @@ -97,7 +97,7 @@ export type Value = struct {
dllimport: bool
dllexport: bool
// Definition of the value
node: weak_ref(parser::Node)
node: weak &parser::Node
state: &typechecking::State
// For imported scopes, this checks if a value is exported before accessing it
// Also used by serialize to signal that a function is imported (ffi)
Expand All @@ -122,7 +122,7 @@ export type Value = struct {
references: &Vector(parser::SourceLoc)
// Don't serialize these
is_generated: bool
module: weak_ref(toolchain::Module)
module: weak &toolchain::Module
}

export def assembly_name(value: &Value, state: &compiler::State) -> Str {
Expand Down Expand Up @@ -198,16 +198,16 @@ export def find_references_to(value: &Value) -> &Vector(parser::SourceLoc) {
}

export type ReExport = struct {
module: weak_ref(toolchain::Module)
module: weak &toolchain::Module
pattern: &parser::Node
}

export type Scope = struct {
module: weak_ref(toolchain::Module)
module: weak &toolchain::Module
is_function: bool
// Counter for local scopes (shadowing)
scope_count: int
parent: weak_ref(Scope)
parent: weak &Scope
fields: &SMap(&Value)
implicits: &Vector(&Value)
// This is a list of imported scopes,
Expand Down Expand Up @@ -938,7 +938,7 @@ export def generate_function(scope: &Scope, node: &parser::Node, parameter_t: &V
for var i in 0..found_member.return_t.length {
var tpe = found_member.return_t(i)
if tpe.kind == typechecking::TypeKind::BOX {
tpe = tpe.weak
tpe = tpe.wk
}
return_t.push(typechecking::copy(tpe))
}
Expand Down Expand Up @@ -970,7 +970,7 @@ export def generate_function(scope: &Scope, node: &parser::Node, parameter_t: &V
module.dyn_dispatch_consteval.push(tpe)

return value
} else if vector::length(parameter_t) == 1 and first_parameter.tpe.kind == typechecking::TypeKind::POINTER and
} else if vector::length(parameter_t) == 1 and is_pointer(first_parameter.tpe) and
name == "__destruct__" and typechecking::has_destructor(first_parameter.tpe.tpe) {

let args = vector::make(typechecking::NamedParameter)
Expand Down
Loading

0 comments on commit 6885b34

Please sign in to comment.