diff options
| -rw-r--r-- | examples/tomodeps/tomodeps.tm | 12 | ||||
| -rw-r--r-- | src/compile.c | 12 | ||||
| -rw-r--r-- | src/typecheck.c | 15 |
3 files changed, 28 insertions, 11 deletions
diff --git a/examples/tomodeps/tomodeps.tm b/examples/tomodeps/tomodeps.tm index 8da64eb2..8c75173a 100644 --- a/examples/tomodeps/tomodeps.tm +++ b/examples/tomodeps/tomodeps.tm @@ -27,7 +27,7 @@ func _get_file_dependencies(file:Path -> {Dependency}): deps:add(Dependency.Module(module_name)) return deps[] -func _build_dependency_graph(dep:Dependency, dependencies:@{Dependency,{Dependency}}): +func _build_dependency_graph(dep:Dependency, dependencies:@{Dependency={Dependency}}): return if dependencies:has(dep) dependencies[dep] = {} # Placeholder @@ -57,7 +57,7 @@ func _build_dependency_graph(dep:Dependency, dependencies:@{Dependency,{Dependen for dep2 in dep_deps: _build_dependency_graph(dep2, dependencies) -func get_dependency_graph(dep:Dependency -> {Dependency,{Dependency}}): +func get_dependency_graph(dep:Dependency -> {Dependency={Dependency}}): graph : @{Dependency={Dependency}} = @{} _build_dependency_graph(dep, graph) return graph @@ -72,7 +72,7 @@ func _printable_name(dep:Dependency -> Text): else: return "$(\x1b)[31;1m$(f) (not found)$(\x1b)[m" -func _draw_tree(dep:Dependency, dependencies:{Dependency,{Dependency}}, already_printed:@{Dependency}, prefix="", is_last=yes): +func _draw_tree(dep:Dependency, dependencies:{Dependency={Dependency}}, already_printed:@{Dependency}, prefix="", is_last=yes): if already_printed:has(dep): say(prefix ++ (if is_last: "└── " else: "├── ") ++ _printable_name(dep) ++ " $\x1b[2m(recursive)$\x1b[m") return @@ -82,16 +82,16 @@ func _draw_tree(dep:Dependency, dependencies:{Dependency,{Dependency}}, already_ child_prefix := prefix ++ (if is_last: " " else: "│ ") - children := dependencies[dep] or {} + children := dependencies[dep] or {/} for i,child in children.items: is_child_last := (i == children.length) _draw_tree(child, dependencies, already_printed, child_prefix, is_child_last) -func draw_tree(dep:Dependency, dependencies:{Dependency,{Dependency}}): +func draw_tree(dep:Dependency, dependencies:{Dependency={Dependency}}): printed : @{Dependency} = @{} say(_printable_name(dep)) printed:add(dep) - deps := dependencies[dep] or {} + deps := dependencies[dep] or {/} for i,child in deps.items: is_child_last := (i == deps.length) _draw_tree(child, dependencies, already_printed=printed, is_last=is_child_last) diff --git a/src/compile.c b/src/compile.c index 21091489..c7e02b3f 100644 --- a/src/compile.c +++ b/src/compile.c @@ -619,6 +619,12 @@ static CORD compile_binary_op(env_t *env, ast_t *ast) } if (ast->tag == Or && lhs_t->tag == OptionalType) { + if (rhs_t->tag == AbortType || rhs_t->tag == ReturnType) { + return CORD_all("({ ", compile_declaration(lhs_t, "lhs"), " = ", compile(env, binop.lhs), "; ", + "if (", check_none(lhs_t, "lhs"), ") ", compile_statement(env, binop.rhs), " ", + optional_into_nonnone(lhs_t, "lhs"), "; })"); + } + if (is_incomplete_type(rhs_t)) { type_t *complete = most_complete_type(rhs_t, Match(lhs_t, OptionalType)->type); if (complete == NULL) @@ -626,11 +632,7 @@ static CORD compile_binary_op(env_t *env, ast_t *ast) rhs_t = complete; } - if (rhs_t->tag == AbortType || rhs_t->tag == ReturnType) { - return CORD_all("({ ", compile_declaration(lhs_t, "lhs"), " = ", compile(env, binop.lhs), "; ", - "if (", check_none(lhs_t, "lhs"), ") ", compile_statement(env, binop.rhs), " ", - optional_into_nonnone(lhs_t, "lhs"), "; })"); - } else if (rhs_t->tag == OptionalType && type_eq(lhs_t, rhs_t)) { + if (rhs_t->tag == OptionalType && type_eq(lhs_t, rhs_t)) { return CORD_all("({ ", compile_declaration(lhs_t, "lhs"), " = ", compile(env, binop.lhs), "; ", check_none(lhs_t, "lhs"), " ? ", compile(env, binop.rhs), " : lhs; })"); } else if (rhs_t->tag != OptionalType && type_eq(Match(lhs_t, OptionalType)->type, rhs_t)) { diff --git a/src/typecheck.c b/src/typecheck.c index 1bef98c8..7b86ec63 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -1055,6 +1055,11 @@ type_t *get_type(env_t *env, ast_t *ast) type_t *lhs_t = get_type(env, binop.lhs); type_t *rhs_t = get_type(env, binop.rhs); + if (binop.lhs->tag == Int && (is_int_type(rhs_t) || rhs_t->tag == ByteType)) + return rhs_t; + else if (binop.rhs->tag == Int && (is_int_type(lhs_t) || lhs_t->tag == ByteType)) + return lhs_t; + // `opt? or (x == y)` / `(x == y) or opt?` is a boolean conditional: if ((lhs_t->tag == OptionalType && rhs_t->tag == BoolType) || (lhs_t->tag == BoolType && rhs_t->tag == OptionalType)) { @@ -1096,6 +1101,11 @@ type_t *get_type(env_t *env, ast_t *ast) type_t *lhs_t = get_type(env, binop.lhs); type_t *rhs_t = get_type(env, binop.rhs); + if (binop.lhs->tag == Int && (is_int_type(rhs_t) || rhs_t->tag == ByteType)) + return rhs_t; + else if (binop.rhs->tag == Int && (is_int_type(lhs_t) || lhs_t->tag == ByteType)) + return lhs_t; + // `and` between optionals/bools is a boolean expression like `if opt? and opt?:` or `if x > 0 and opt?:` if ((lhs_t->tag == OptionalType || lhs_t->tag == BoolType) && (rhs_t->tag == OptionalType || rhs_t->tag == BoolType)) { @@ -1125,6 +1135,11 @@ type_t *get_type(env_t *env, ast_t *ast) type_t *lhs_t = get_type(env, binop.lhs); type_t *rhs_t = get_type(env, binop.rhs); + if (binop.lhs->tag == Int && (is_int_type(rhs_t) || rhs_t->tag == ByteType)) + return rhs_t; + else if (binop.rhs->tag == Int && (is_int_type(lhs_t) || lhs_t->tag == ByteType)) + return lhs_t; + // `xor` between optionals/bools is a boolean expression like `if opt? xor opt?:` or `if x > 0 xor opt?:` if ((lhs_t->tag == OptionalType || lhs_t->tag == BoolType) && (rhs_t->tag == OptionalType || rhs_t->tag == BoolType)) { |
