Skip to content

Commit

Permalink
Make the tests pass
Browse files Browse the repository at this point in the history
  • Loading branch information
Victorious3 committed Aug 2, 2022
1 parent b89be0d commit 32046f2
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 91 deletions.
114 changes: 63 additions & 51 deletions src/compiler.pr
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ export type State = struct {
scope: weak_ref(scope::Scope)
// Destructor function
finalizer: &Function
consteval: bool
}

export def destruct(state: *State) {
Expand Down Expand Up @@ -5020,24 +5021,19 @@ def walk_Assert(node: &parser::Node, state: &State) {

var msg: &string = ""
var line = cond.loc.lines[cond.loc.line]
var str: string
str.value = line.value ++ cond.loc.column
if cond.loc.end_line == cond.loc.line {
str.size = cond.loc.end_column - cond.loc.column + 1
msg += line.substring(cond.loc.column, min(line.length - 1, cond.loc.end_column) !size_t) // TODO This is kinda weird
} else {
str.size = line.size - cond.loc.column - 1
msg += line.substring(cond.loc.column, line.length - 1)
}
msg += str

// TODO This doesn't work at all
for var i in cond.loc.line..(cond.loc.end_line - 1) {
msg += cond.loc.lines[i]
}
if cond.loc.end_line > cond.loc.line {
line = cond.loc.lines[cond.loc.end_line]
str.value = line.value
str.size = cond.loc.end_column
msg += str
msg += line.substring(0, min(line.length - 1, cond.loc.end_column) !size_t)
}

args[5] = charp(msg, state)
Expand Down Expand Up @@ -5981,10 +5977,10 @@ def make_string(str: &string, state: &State) -> Value {

// TODO This is not going to work for nested type decls (we don't reset the state)
def walk_TypeDecl(node: &parser::Node, state: &State) {
let left = (@node).value.type_decl.left
let left = node.value.type_decl.left
for var i in 0..vector::length(left) {
let n = left[i]
let tpe = (@n).tpe
let tpe = n.tpe
if not tpe { continue }
if typechecking::is_struct(tpe) {
import_structures(tpe, state.module)
Expand Down Expand Up @@ -6683,7 +6679,9 @@ def push_tpe_tpe(tpe: &typechecking::Type, global: Value, module: &toolchain::Mo

var value: Value
if tpe.tpe {
value = @create_type(tpe.tpe, module)
let v = create_type(tpe.tpe, module)
if not v { return }
value = @v
} else {
value = { kind = ValueKind::NULL, tpe = pointer(builtins::Type_) } !Value
}
Expand All @@ -6706,7 +6704,9 @@ def push_struct_members(tpe: &typechecking::Type, global: Value, module: &toolch
let fields = make_global_value(fields_sarray, "fields", null, state)
for var i in 0..tpe.fields.size {
let field = tpe.fields[i]
typechecking::lookup_struct_member(field)
if not state.consteval {
typechecking::lookup_struct_member(field)
}
let fname = field.name if field.name != null else to_string(i)

let name_values = allocate_ref(Value, 2)
Expand Down Expand Up @@ -7244,43 +7244,45 @@ def do_create_type(tpe: &typechecking::Type, svalue: &scope::Value, module: &too
value.kind = ValueKind::STRUCT
value.tpe = builtins::Type_

let old_cstate_block = consteval::compiler_state.current_block
let old_cstate_function = consteval::compiler_state.current_function
old_block.counter = new_block.counter
for var i in 0..vector::length(new_block.insn) {
old_block.insn.push(new_block.insn[i])
}

let function = {
name = "__main__",
unmangled = "__main__",
forward_declare = true,
allocas = vector::make(type &Insn),
block = new_block,
function_locals = set::make()
} !&Function
if state.consteval {
let old_cstate_block = consteval::compiler_state.current_block
let old_cstate_function = consteval::compiler_state.current_function

consteval::compiler_state.current_function = function
consteval::compiler_state.current_block = new_block

// Copy constants into the right module
// TODO This always copies the whole thing
let keys = map::keys(toolchain::types.result.globals)
for var i in 0..keys.size {
let key = keys[i]
let global = toolchain::types.result.globals[key]
consteval::const_module.result.globals[key] = global
}
let function = {
name = "__main__",
unmangled = "__main__",
forward_declare = true,
allocas = vector::make(type &Insn),
block = new_block,
function_locals = set::make()
} !&Function

let old_module = consteval::compiler_state.module
consteval::compiler_state.module = consteval::const_module
eval::eval(consteval::compiler_state)
consteval::compiler_state.module = old_module
consteval::compiler_state.current_function = function
consteval::compiler_state.current_block = new_block

// Copy constants into the right module
// TODO This always copies the whole thing
let keys = map::keys(toolchain::types.result.globals)
for var i in 0..keys.size {
let key = keys[i]
let global = toolchain::types.result.globals[key]
consteval::const_module.result.globals[key] = global
}

old_block.counter = new_block.counter
for var i in 0..vector::length(new_block.insn) {
old_block.insn.push(new_block.insn[i])
let old_module = consteval::compiler_state.module
consteval::compiler_state.module = consteval::const_module
eval::eval(consteval::compiler_state)
consteval::compiler_state.module = old_module
consteval::compiler_state.current_block = old_cstate_block
consteval::compiler_state.current_function = old_cstate_function
}
state.current_block = old_block

consteval::compiler_state.current_block = old_cstate_block
consteval::compiler_state.current_function = old_cstate_function
state.current_block = old_block

return value
}
Expand All @@ -7305,8 +7307,7 @@ export def resolve_types {
let ident = make_identifier(debug::type_to_str(tpe, true))
ident.loc.module = "type"

let svalue = scope::get(toolchain::types.scope, ident)
svalue.value = do_create_type(tpe, svalue, to_resolve.module)
create_type(tpe, to_resolve.module)
}
}

Expand All @@ -7316,12 +7317,19 @@ export def create_type(tpe: &typechecking::Type, module: &toolchain::Module) ->
if generic and generic.tc_incomplete { return null }
if tpe.kind == typechecking::TypeKind::TYPE_DEF { return null }

let name = debug::type_to_str(tpe, full_name = true)
if tpe.kind == typechecking::TypeKind::STUB {
let to_resolve = { module, tpe } !ToResolve
types_to_resolve[debug::type_to_str(tpe, full_name = true)] = to_resolve
if name {
let to_resolve = { module, tpe } !ToResolve
types_to_resolve[name] = to_resolve
} else {
return null
}
}

let ident = make_identifier(debug::type_to_str(tpe, true))
import_structure(builtins::Type_, toolchain::types)

let ident = make_identifier(name)
ident.loc.module = "type"

var svalue = scope::get(toolchain::types.scope, ident, false, false)
Expand All @@ -7336,11 +7344,14 @@ export def create_type(tpe: &typechecking::Type, module: &toolchain::Module) ->
ident, parser::ShareMarker::NONE, parser::VarDecl::CONST,
builtins::Type_, do_create_type(tpe, svalue, module))
}
if not map::contains(module.result.globals, svalue.assembly_name) {

if not toolchain::types_state.consteval and
not map::contains(module.result.globals, svalue.assembly_name) {

let global = {
external = true,
name = svalue.assembly_name,
tpe = svalue.tpe,
tpe = builtins::Type_,
line = -1
} !&Global
module.result.globals[global.name] = global
Expand Down Expand Up @@ -7494,6 +7505,7 @@ def generate_vtable_function(function: &Function, tpe: &typechecking::Type, stat
}
}

if not function { continue }
predeclare_function(function, state.module)
state.module.imported.add(function.type_name)

Expand Down Expand Up @@ -7733,7 +7745,7 @@ export def compile(state: &State, is_main: bool, no_cleanup: bool = false) {
} !typechecking::NamedParameter)

let main_tpe = typechecking::make_function_type_n(ident, args, vector::make(type &typechecking::Type), state.module)
//scope::create_function(node.scope, ident, parser::ShareMarker::EXPORT, main_tpe)
scope::create_function(node.scope, ident, parser::ShareMarker::EXPORT, main_tpe)

for var i in 0..vector::length(state.module.dyn_dispatch) {
let tpe = state.module.dyn_dispatch[i]
Expand Down
3 changes: 2 additions & 1 deletion src/consteval.pr
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export let const_module = toolchain::make_module(
const_module.scope.module = const_module

// This is for compiling expressions
export let compiler_state = compiler::make_state(const_module )
export let compiler_state = compiler::make_state(const_module)

import eval

Expand Down Expand Up @@ -354,6 +354,7 @@ def walk_TypeDecl(node: &parser::Node, state: &typechecking::State) {
scope::create_type(state.scope, name, share, tpe, scope::Phase::DECLARED, null, null)
}

left.tpe = tpe
let index = parent.body.index_of(node)
parent.body.remove(index)
}
Expand Down
5 changes: 3 additions & 2 deletions src/eval.pr
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,7 @@ def serialize(is_constant: *bool, value: compiler::Value, global: &compiler::Glo
let array_value = { kind = compiler::ValueKind::ARRAY, tpe = value.tpe, values = values } !compiler::Value

let tpe = typechecking::make_type_raw(typechecking::TypeKind::STATIC_ARRAY)
tpe.tpe = builtins::char_
tpe._tpe = builtins::char_
tpe.length = length
tpe.size = tpe.length * value.tpe.tpe.size
tpe.align = value.tpe.tpe.align
Expand Down Expand Up @@ -1306,7 +1306,8 @@ export def eval(cstate: &compiler::State) -> &State {
export def serialize_value(key: &string, module: &toolchain::Module, cstate: &compiler::State) -> &compiler::Global {
cstate.current_block = module.code

let mem = cstate.globals[key]
let mem = cstate.globals.get_or_default(key, null)
if not mem { return null }
let global = cstate.module.result.globals.get_or_default(key, null)
if not global { return null } // Probably a constant
if typechecking::is_stub(global.tpe) { return null } // Didn't reference
Expand Down
8 changes: 4 additions & 4 deletions src/getopt.pr
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def print_help(parser: *OptionParser, program: &string) {
for var i in 0..options.size {
let option = *options[i]
if not starts_with(option.longop, "--") {
if not option.metavar.value { continue }
if not option.metavar { continue }
if not option.default {
print(option.metavar)
} else {
Expand Down Expand Up @@ -196,7 +196,7 @@ def print_help(parser: *OptionParser, program: &string) {
}
size += print(option.longop)

if option.metavar.value {
if option.metavar {
size += print(" <", option.metavar, "> ")
}
if size >= INDENT {
Expand Down Expand Up @@ -295,7 +295,7 @@ export def parse(option_parser: *OptionParser, args: [string]) -> bool {
error("Invalid number of arguments to option ", arg, "\n")
return false
}
value.str = arg.substring(length(option.longop) + 1, length(arg))
value.str = arg.substring(length(option.longop) + 1, length(arg) - 1)
i += 1
} else {
if option.nargs == 1 {
Expand Down Expand Up @@ -346,7 +346,7 @@ export def parse(option_parser: *OptionParser, args: [string]) -> bool {
} else if option.nargs == 1 and j < length(arg) - 1 {
value.kind = ValueKind::STRING
// parse -XArg
value.str = arg.substring(j + 1, length(arg))
value.str = arg.substring(j + 1, length(arg) - 1)
i += 1
j = length(arg) !int - 1
} else if j == length(arg) - 1 {
Expand Down
2 changes: 1 addition & 1 deletion src/lexer.pr
Original file line number Diff line number Diff line change
Expand Up @@ -307,12 +307,12 @@ def parse_simple_escape_sequence(escape_char: char) -> int {
// TODO Use a state instead of passing all of these parameters one by one
def next_char(s: &string, i: *int, line: *int, column: *int) -> char {
@i += 1
@column += 1
if @i >= length(s) {
return 0x1A !char
}

let c = s[@i]
@column += 1
return c
}

Expand Down
19 changes: 15 additions & 4 deletions src/parser.pr
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ export type NodeProgram = struct {
// Map of typechecking::Type
locals: &SMap(&typechecking::Type)
has_defer: bool
body: &Vector(&Node)
}

export type NodeValue = struct #union {
Expand Down Expand Up @@ -392,10 +393,12 @@ export type Node = struct {

export def destruct(node: *Node) {
switch node.kind {
case NodeKind::PROGRAM, NodeKind::LOOP, NodeKind::ELSE, NodeKind::DEFER,
case NodeKind::LOOP, NodeKind::ELSE, NodeKind::DEFER,
NodeKind::RETURN, NodeKind::IMPORT, NodeKind::ARRAY_LIT,
NodeKind::STRUCT_T, NodeKind::UNION_T, NodeKind::STRUCTURAL_T:
__destruct__(*node.value.body)
case NodeKind::PROGRAM:
__destruct__(*node.value.program)
case NodeKind::ASSERT:
__destruct__(*node.value.assert_)
case NodeKind::IF, NodeKind::STATIC_IF:
Expand Down Expand Up @@ -487,7 +490,10 @@ export def construct(copy: *Node, node: *Node) {
copy.variants = node.variants

switch node.kind {
case NodeKind::PROGRAM, NodeKind::LOOP, NodeKind::ELSE, NodeKind::DEFER:
case NodeKind::PROGRAM:
copy.value.program = node.value.program
copy.body = node.value.program.body
case NodeKind::LOOP, NodeKind::ELSE, NodeKind::DEFER:
copy.value.body = node.value.body
copy.body = copy.value.body
case NodeKind::RETURN, NodeKind::IMPORT, NodeKind::ARRAY_LIT,
Expand Down Expand Up @@ -626,7 +632,10 @@ export def deep_copy_node(node: &Node) -> &Node {
copy.tpe = typechecking::copy(node.tpe)

switch node.kind {
case NodeKind::PROGRAM, NodeKind::LOOP, NodeKind::ELSE, NodeKind::DEFER:
case NodeKind::PROGRAM:
copy.value.program.body = deep_copy_vector_of_nodes(node.value.program.body)
copy.body = copy.value.program.body
case NodeKind::LOOP, NodeKind::ELSE, NodeKind::DEFER:
copy.value.body = deep_copy_vector_of_nodes(node.value.body)
copy.body = copy.value.body
case NodeKind::RETURN, NodeKind::IMPORT, NodeKind::ARRAY_LIT,
Expand Down Expand Up @@ -3231,7 +3240,9 @@ export def parse(list: &lexer::TokenList, lines: &[&string], filename: &string,
}

let program_node = make_node(NodeKind::PROGRAM, 0, 0, parse_state)
program_node.value.body = vec
program_node.value.program = {
body = vec
} !NodeProgram
program_node.body = vec

let end = util::millis()
Expand Down
6 changes: 4 additions & 2 deletions src/test/test_compiler.pr
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ def compile(s: &string) -> &string {

consteval::consteval(module)
typechecking::typecheck(module)

toolchain::load_file_type()
toolchain::reset_types()

compiler::compile(module)
codegen::gen(module)

let fh = open("./build/main.ll", "r")
let buf = util::read_all(fh)
close(fh)
Expand Down
4 changes: 2 additions & 2 deletions src/test/test_typechecking.pr
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ export def run_tests {
|main@6:9
| bar = \"string\"
| ^~~~
|Incompatible types [char] and int
|Incompatible types, can't assign [char] to int
|
|main@2:14
| var v
Expand Down Expand Up @@ -650,5 +650,5 @@ export def run_tests {
|main@4:9
| a = no_return()
| ^~
|Incompatible types void and int\n"))
|Incompatible types, can't assign void to int\n"))
}
Loading

0 comments on commit 32046f2

Please sign in to comment.