Skip to content

Commit

Permalink
Fix test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
Victorious3 committed Mar 2, 2024
1 parent 0ee7043 commit b98d1a1
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 15 deletions.
37 changes: 36 additions & 1 deletion src/compiler.pr
Original file line number Diff line number Diff line change
Expand Up @@ -1035,7 +1035,7 @@ def push_scope(node: &parser::Node, state: &State) {
if state.current_function.has_yield {
state.current_function.current_snapshot.push(map::make(int))
}

if not toolchain::debug_sym { return }
let discope = vector::peek(state.discope) if state.discope.length > 0 else null !&Value

Expand Down Expand Up @@ -2026,6 +2026,38 @@ def convert_static_array_to_tuple(tpe: &typechecking::Type, value: Value, loc: &
return ret
}

def convert_anon_to_struct(tpe: &typechecking::Type, value: Value, loc: &Value, state: &State) -> Value {
if tpe.field_types.length != value.tpe.field_types.length { return NO_VALUE }

var fast_path = true
for var i in 0..tpe.field_types.length {
let tpea = tpe.field_types(i).tpe
let tpeb = value.tpe.field_types(i).tpe
if not typechecking::equals(tpea, tpeb) {
fast_path = false
break
}
}

if fast_path { return value }

var res = [ kind = ValueKind::UNDEF, tpe = tpe ] !Value
for var fielda in @value.tpe.fields {
let member = state.extract_value(value.tpe.field_types(fielda.index).tpe, value, [fielda.index !int], loc)

var index = fielda.index
for var fieldb in @tpe.fields {
if fieldb.name == fielda.name {
index = fieldb.index
break
}
}
res = state.insert_value(tpe, res, member, [index !int], loc)
}

return res
}

export def convert_to(node: &parser::Node, value: Value, tpe: &typechecking::Type, state: &State) -> Value {
let loc = make_location(node, state)
return convert_to(loc, value, tpe, state)
Expand Down Expand Up @@ -2081,6 +2113,9 @@ def convert_to(loc: &Value, value: Value, tpe: &typechecking::Type, state: &Stat
return value
}
}
if tpe.kind == value.tpe.kind and value.tpe.is_anon and typechecking::is_struct(value.tpe) {
return convert_anon_to_struct(tpe, value, loc, state)
}
if tpe.kind == typechecking::TypeKind::TUNION {
if value.tpe.kind == typechecking::TypeKind::TUNION {
return convert_variant_to_variant(tpe, value, loc, state)
Expand Down
1 change: 1 addition & 0 deletions src/debug.pr
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,7 @@ export def type_to_str(tpe: &typechecking::Type, full_name: bool = false) -> Str
typechecking::TypeKind::STRUCT, typechecking::TypeKind::UNION,
typechecking::TypeKind::STRUCTURAL,
typechecking::TypeKind::TYPE_CONSTRUCTOR
if tpe.is_anon { return "<anonymous>" }
return tpe.type_name if full_name else tpe.name
case typechecking::TypeKind::TYPE
return "type"
Expand Down
19 changes: 19 additions & 0 deletions src/typechecking.pr
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ export type Type = struct {
// This gets set if it might also be a type argument, in that case we also consider the overload with a type
// As an example, consider [int], this might be an array of types or an array type
may_be_type: &Type
// True if this is an anonymous struct. name should be "<anonymous>"
is_anon: bool
}

export def hash(tpe: &Type) -> uint64 {
Expand Down Expand Up @@ -1482,6 +1484,22 @@ export def convert_type_score(a: &Type, b: &Type, module: &toolchain::Module, is
if equals(a, b) {
return 0
}
// Convert anonymous struct to value
if a.kind == b.kind and b.kind == TypeKind::STRUCT and b.is_anon {
if a.fields.size != b.fields.size { return -1 }
for var af in @a.fields {
var found = false
for var bf in @b.fields {
if equals(af.tpe, bf.tpe) and af.name == bf.name {
found = true
break
}
}
if not found { return -1 }
}
return 11
}

if a.kind == TypeKind::UNDEF or b.kind == TypeKind::UNDEF { return 0 }

if (a.kind == TypeKind::REFERENCE or a.kind == TypeKind::WEAK_REF) and
Expand Down Expand Up @@ -5426,6 +5444,7 @@ def walk_StructLit(node: &parser::Node, state: &State) {
}

tpe = make_struct_type(fields)
tpe.is_anon = true
node.tpe = tpe

return
Expand Down
4 changes: 2 additions & 2 deletions std/std.pr
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ def print_val(file: File, ref: runtime::Ref) -> int {
} else if tpe.kind == runtime::TypeKind::STRUCT or tpe.kind == runtime::TypeKind::UNION {
let fields = tpe.fields
var sum = 0
sum += cstd::fprintf(file, "{".value)
sum += cstd::fprintf(file, "[".value)
for var i in 0..fields.size {
let field = fields(i)
sum += cstd::fprintf(file, "%s = ".value, field.name.value)
Expand All @@ -418,7 +418,7 @@ def print_val(file: File, ref: runtime::Ref) -> int {
sum += cstd::fprintf(file, ", ".value)
}
}
sum += cstd::fprintf(file, "} !%s".value, tpe.name.value)
sum += cstd::fprintf(file, "] !%s".value, tpe.name.value)
return sum
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/runtime/test_vector.pr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ let INITIAL_SIZE = 8

type Vector = struct {
length: size_t
data: (&)
data: [&]
}

type S = struct { a: int }
Expand Down
2 changes: 1 addition & 1 deletion test/test_compiler.pr
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ def #test test_struct_lit {
return [a = 10]
}

let h: A = {10}
let h: A = [a = 10]
var i: A
i = [a = 10]

Expand Down
4 changes: 2 additions & 2 deletions test/test_lexer.pr
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ def #test test_complex {
{ "kind": "WHITESPACE", "line": 7, "column": 20 },
{ "kind": "OP_ASSIGN", "line": 7, "column": 21 },
{ "kind": "WHITESPACE", "line": 7, "column": 22 },
{ "kind": "O_BRACE", "line": 7, "column": 23 },
{ "kind": "O_SQUARE", "line": 7, "column": 23 },
{ "kind": "NEW_LINE", "line": 7, "column": 24 },
{ "kind": "WHITESPACE", "line": 8, "column": 0 },
{ "kind": "IDENTIFIER", "line": 8, "column": 16, "value": "a" },
Expand All @@ -338,7 +338,7 @@ def #test test_complex {
{ "kind": "WHITESPACE", "line": 8, "column": 26 },
{ "kind": "STRING", "line": 8, "column": 27, "value": "Test string" },
{ "kind": "WHITESPACE", "line": 8, "column": 40 },
{ "kind": "C_BRACE", "line": 8, "column": 41 },
{ "kind": "C_SQUARE", "line": 8, "column": 41 },
{ "kind": "WHITESPACE", "line": 8, "column": 42 },
{ "kind": "OP_CAST", "line": 8, "column": 43 },
{ "kind": "IDENTIFIER", "line": 8, "column": 44, "value": "T" },
Expand Down
11 changes: 6 additions & 5 deletions test/test_parser.pr
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def #test test_identifiers {
}]
}"""))

assert parse("foo::bar::(int, () -> ())") == program(json::parse("""{
assert parse("foo::bar::(int, [] -> [])") == program(json::parse("""{
"kind": "Identifier",
"path": [
"foo",
Expand All @@ -70,7 +70,7 @@ def #test test_identifiers {
]
}"""))

assert parse("foo::bar::(int, () -> ())") == program(json::parse("""{\
assert parse("foo::bar::(int, [] -> [])") == program(json::parse("""{\
"kind": "Identifier", "path": ["foo", "bar"],
"prefixed": false,
"args": [{
Expand Down Expand Up @@ -4462,8 +4462,8 @@ def #test test_array_literal {
"kind": "Program",
"body": [
{
"kind": "ArrayLit",
"body": [
"kind": "StructLit",
"args": [
{
"kind": "Integer",
"value": 1.00000
Expand All @@ -4476,7 +4476,8 @@ def #test test_array_literal {
"kind": "Integer",
"value": 3.00000
}
]
],
"kwargs": []
}
]
}""")
Expand Down
4 changes: 2 additions & 2 deletions test/test_runtime.pr
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ def #test test_ucs {
def inc(a: int) -> int { return a + 1}

def test_ucs {
let s: Struct2 = [a = 10, t = null]
let s = [a = 10, t = null] !Struct2

assert s.function() == 10
assert s.function.inc == 11
Expand All @@ -491,7 +491,7 @@ def #test test_anonymous {

def test_anonymous {
var s: Struct3
s = [a = 10, b = [c = 20, d = 30]]
s = [a = 10] !Struct3
s.a = 10
s.b = [c = 20, d = 30]
s.e = 0x4034800000000000
Expand Down
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION=0.3.10
VERSION=0.3.11

0 comments on commit b98d1a1

Please sign in to comment.