aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-04-06 19:20:07 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-04-06 19:20:07 -0400
commit1d2e55f53dfab5153dbfd0c03f28cd9daedb3b77 (patch)
treeaa1c21191800467abe0b3d16cb6c2a0c2e4587f9
parentbc93dea8186168aa015b05a615bc1873173393b5 (diff)
Allow uninitialized variables when there's a sensible empty value
(defaults to empty/zero value)
-rw-r--r--examples/colorful/colorful.tm2
-rw-r--r--examples/commands/commands.tm4
-rw-r--r--examples/http-server/connection-queue.tm2
-rw-r--r--examples/http-server/http-server.tm4
-rw-r--r--examples/http/http.tm2
-rw-r--r--examples/ini/ini.tm4
-rw-r--r--examples/learnxiny.tm4
-rw-r--r--examples/log/log.tm2
-rw-r--r--examples/tomo-install/tomo-install.tm4
-rw-r--r--examples/tomodeps/tomodeps.tm10
-rw-r--r--examples/wrap/wrap.tm4
-rw-r--r--src/compile.c154
-rw-r--r--src/parse.c16
-rw-r--r--src/typecheck.c5
-rw-r--r--test/arrays.tm6
-rw-r--r--test/defer.tm2
-rw-r--r--test/import.tm4
-rw-r--r--test/iterators.tm2
-rw-r--r--test/reductions.tm2
19 files changed, 157 insertions, 76 deletions
diff --git a/examples/colorful/colorful.tm b/examples/colorful/colorful.tm
index d878b662..30f3fc12 100644
--- a/examples/colorful/colorful.tm
+++ b/examples/colorful/colorful.tm
@@ -141,7 +141,7 @@ struct _TermState(
)
func apply(old,new:_TermState -> Text)
- sequences : &[Text] = &[]
+ sequences : &[Text]
_toggle2(sequences, old.bold, old.dim, new.bold, new.dim, "1", "2", "22")
_toggle2(sequences, old.italic, old.fraktur, new.italic, new.fraktur, "3", "20", "23")
_toggle(sequences, old.underline, new.underline, "4", "24")
diff --git a/examples/commands/commands.tm b/examples/commands/commands.tm
index 2dd5aaf7..81c43692 100644
--- a/examples/commands/commands.tm
+++ b/examples/commands/commands.tm
@@ -54,8 +54,8 @@ struct Command(command:Text, args:[Text]=[], env:{Text=Text}={})
if input.length > 0
(&input_bytes).insert_all(input.bytes())
- stdout : [Byte] = []
- stderr : [Byte] = []
+ stdout : [Byte]
+ stderr : [Byte]
status := run_command(command.command, command.args, command.env, input_bytes, &stdout, &stderr)
if inline C : Bool { WIFEXITED(_$status) }
diff --git a/examples/http-server/connection-queue.tm b/examples/http-server/connection-queue.tm
index 29759f38..c56069e1 100644
--- a/examples/http-server/connection-queue.tm
+++ b/examples/http-server/connection-queue.tm
@@ -12,7 +12,7 @@ struct ConnectionQueue(_connections:@[Int32]=@[], _mutex=pthread_mutex_t.new(),
func dequeue(queue:ConnectionQueue -> Int32)
- conn : Int32? = none
+ conn : Int32?
queue._mutex.lock()
diff --git a/examples/http-server/http-server.tm b/examples/http-server/http-server.tm
index b814cdcb..92651ca1 100644
--- a/examples/http-server/http-server.tm
+++ b/examples/http-server/http-server.tm
@@ -17,7 +17,7 @@ use ./connection-queue.tm
func serve(port:Int32, handler:func(request:HTTPRequest -> HTTPResponse), num_threads=16)
connections := ConnectionQueue()
- workers : &[@pthread_t] = &[]
+ workers : &[@pthread_t]
for i in num_threads
workers.insert(pthread_t.new(func()
repeat
@@ -114,7 +114,7 @@ enum RouteEntry(ServeFile(file:Path), Redirect(destination:Text))
return HTTPResponse("Found", 302, headers={"Location"=destination})
func load_routes(directory:Path -> {Text=RouteEntry})
- routes : &{Text=RouteEntry} = &{}
+ routes : &{Text=RouteEntry}
for file in (directory ++ (./*)).glob()
skip unless file.is_file()
contents := file.read() or skip
diff --git a/examples/http/http.tm b/examples/http/http.tm
index 39cbfd6d..29727e6e 100644
--- a/examples/http/http.tm
+++ b/examples/http/http.tm
@@ -8,7 +8,7 @@ struct HTTPResponse(code:Int, body:Text)
enum _Method(GET, POST, PUT, PATCH, DELETE)
func _send(method:_Method, url:Text, data:Text?, headers:[Text]=[] -> HTTPResponse)
- chunks : @[Text] = @[]
+ chunks : @[Text]
save_chunk := func(chunk:CString, size:Int64, n:Int64)
chunks.insert(inline C:Text {
Text$format("%.*s", _$size*_$n, _$chunk)
diff --git a/examples/ini/ini.tm b/examples/ini/ini.tm
index 7d53d7e5..c24cb4b9 100644
--- a/examples/ini/ini.tm
+++ b/examples/ini/ini.tm
@@ -11,8 +11,8 @@ _HELP := "
func parse_ini(path:Path -> {Text={Text=Text}})
text := path.read() or exit("Could not read INI file: $\[31;1]$(path)$\[]")
- sections : @{Text=@{Text=Text}} = @{}
- current_section : @{Text=Text} = @{}
+ sections : @{Text=@{Text=Text}}
+ current_section : @{Text=Text}
# Line wraps:
text = text.replace_pattern($Pat/\{1 nl}{0+space}/, " ")
diff --git a/examples/learnxiny.tm b/examples/learnxiny.tm
index 5bf8e69f..31d768eb 100644
--- a/examples/learnxiny.tm
+++ b/examples/learnxiny.tm
@@ -56,7 +56,7 @@ func main()
my_numbers := [10, 20, 30]
# Empty arrays require specifying the type:
- empty_array : [Int] = []
+ empty_array : [Int]
>> empty_array.length
= 0
@@ -120,7 +120,7 @@ func main()
= 0
# Empty tables require specifying the key and value types:
- empty_table : {Text=Int} = {}
+ empty_table : {Text=Int}
# Tables can be iterated over either by key or key,value:
for key in table
diff --git a/examples/log/log.tm b/examples/log/log.tm
index 3763303f..94984b81 100644
--- a/examples/log/log.tm
+++ b/examples/log/log.tm
@@ -3,7 +3,7 @@ use <stdio.h>
timestamp_format := CString("%F %T")
-logfiles : @|Path| = @||
+logfiles : @|Path|
func _timestamp(->Text)
c_str := inline C:CString {
diff --git a/examples/tomo-install/tomo-install.tm b/examples/tomo-install/tomo-install.tm
index fd8b3c40..c7d752ee 100644
--- a/examples/tomo-install/tomo-install.tm
+++ b/examples/tomo-install/tomo-install.tm
@@ -11,7 +11,7 @@ _HELP := "
"
func find_urls(path:Path -> [Text])
- urls : @[Text] = @[]
+ urls : @[Text]
if path.is_directory()
for f in path.children()
urls.insert_all(find_urls(f))
@@ -40,7 +40,7 @@ func main(paths:[Path])
say("Already installed: $url")
skip
- alias : Text? = none
+ alias : Text?
curl_flags := ["-L"]
if github := url_without_protocol.pattern_captures($Pat"github.com/{!/}/{!/}#{..}")
user := github[1]
diff --git a/examples/tomodeps/tomodeps.tm b/examples/tomodeps/tomodeps.tm
index 1181f2be..1e6be615 100644
--- a/examples/tomodeps/tomodeps.tm
+++ b/examples/tomodeps/tomodeps.tm
@@ -16,7 +16,7 @@ func _get_file_dependencies(file:Path -> |Dependency|)
say("Could not read file: $file")
return ||
- deps : @|Dependency| = @||
+ deps : @|Dependency|
if lines := file.by_line()
for line in lines
if line.matches_pattern($Pat/use {..}.tm/)
@@ -36,8 +36,8 @@ func _build_dependency_graph(dep:Dependency, dependencies:@{Dependency=|Dependen
_get_file_dependencies(path)
is Module(module)
dir := (~/.local/share/tomo/installed/$module)
- module_deps : @|Dependency| = @||
- visited : @|Path| = @||
+ module_deps : @|Dependency|
+ visited : @|Path|
unvisited := @|f.resolved() for f in dir.files() if f.extension() == ".tm"|
while unvisited.length > 0
file := unvisited.items[-1]
@@ -58,7 +58,7 @@ func _build_dependency_graph(dep:Dependency, dependencies:@{Dependency=|Dependen
_build_dependency_graph(dep2, dependencies)
func get_dependency_graph(dep:Dependency -> {Dependency=|Dependency|})
- graph : @{Dependency=|Dependency|} = @{}
+ graph : @{Dependency=|Dependency|}
_build_dependency_graph(dep, graph)
return graph
@@ -88,7 +88,7 @@ func _draw_tree(dep:Dependency, dependencies:{Dependency=|Dependency|}, already_
_draw_tree(child, dependencies, already_printed, child_prefix, is_child_last)
func draw_tree(dep:Dependency, dependencies:{Dependency=|Dependency|})
- printed : @|Dependency| = @||
+ printed : @|Dependency|
say(_printable_name(dep))
printed.add(dep)
deps := dependencies[dep] or ||
diff --git a/examples/wrap/wrap.tm b/examples/wrap/wrap.tm
index 303393ee..1a29701f 100644
--- a/examples/wrap/wrap.tm
+++ b/examples/wrap/wrap.tm
@@ -33,7 +33,7 @@ func wrap(text:Text, width:Int, min_split=3, hyphen="-" -> Text)
... and I can't split it without splitting into chunks smaller than $min_split.
")
- lines : @[Text] = @[]
+ lines : @[Text]
line := ""
for word in text.split($/{whitespace}/)
letters := word.split()
@@ -93,7 +93,7 @@ func main(files:[Path], width=80, inplace=no, min_split=3, rewrap=yes, hyphen=UN
(/dev/stdout)
first := yes
- wrapped_paragraphs : @[Text] = @[]
+ wrapped_paragraphs : @[Text]
for paragraph in text.split($/{2+ nl}/)
wrapped_paragraphs.insert(
wrap(paragraph, width=width, min_split=min_split, hyphen=hyphen)
diff --git a/src/compile.c b/src/compile.c
index 1df56f3e..0b7f19f5 100644
--- a/src/compile.c
+++ b/src/compile.c
@@ -31,6 +31,8 @@ static CORD compile_int_to_type(env_t *env, ast_t *ast, type_t *target);
static CORD compile_unsigned_type(type_t *t);
static CORD promote_to_optional(type_t *t, CORD code);
static CORD compile_none(type_t *t);
+static CORD compile_empty(type_t *t);
+static CORD compile_declared_value(env_t *env, ast_t *declaration_ast);
static CORD compile_to_type(env_t *env, ast_t *ast, type_t *t);
static CORD compile_typed_array(env_t *env, ast_t *ast, type_t *array_type);
static CORD compile_typed_set(env_t *env, ast_t *ast, type_t *set_type);
@@ -214,7 +216,8 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t
break;
}
case Declare: {
- add_closed_vars(closed_vars, enclosing_scope, env, Match(ast, Declare)->value);
+ ast_t *value = Match(ast, Declare)->value;
+ add_closed_vars(closed_vars, enclosing_scope, env, value);
bind_statement(env, ast);
break;
}
@@ -334,6 +337,8 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t
if (condition->tag == Declare) {
env_t *truthy_scope = fresh_scope(env);
bind_statement(truthy_scope, condition);
+ if (!Match(condition, Declare)->value)
+ code_err(condition, "This declared variable must have an initial value");
add_closed_vars(closed_vars, enclosing_scope, env, Match(condition, Declare)->value);
ast_t *var = Match(condition, Declare)->var;
type_t *cond_t = get_type(truthy_scope, var);
@@ -1132,17 +1137,9 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
CORD test_code;
if (test->expr->tag == Declare) {
auto decl = Match(test->expr, Declare);
- const char *varname = Match(decl->var, Var)->name;
- if (streq(varname, "_"))
- return compile_statement(env, WrapAST(ast, DocTest, .expr=decl->value, .expected=test->expected, .skip_source=test->skip_source));
- CORD var = CORD_all("_$", Match(decl->var, Var)->name);
type_t *t = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value);
- if (!t) code_err(decl->value, "I couldn't figure out the type of this value!");
- CORD val_code = compile_maybe_incref(env, decl->value, t);
- if (t->tag == FunctionType) {
- assert(promote(env, decl->value, &val_code, t, Type(ClosureType, t)));
- t = Type(ClosureType, t);
- }
+ CORD var = CORD_all("_$", Match(decl->var, Var)->name);
+ CORD val_code = compile_declared_value(env, test->expr);
setup = CORD_all(compile_declaration(t, var), ";\n");
test_code = CORD_all("(", var, " = ", val_code, ")");
expr_t = t;
@@ -1229,17 +1226,16 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
auto decl = Match(ast, Declare);
const char *name = Match(decl->var, Var)->name;
if (streq(name, "_")) { // Explicit discard
- return CORD_all("(void)", compile(env, decl->value), ";");
+ if (decl->value)
+ return CORD_all("(void)", compile(env, decl->value), ";");
+ else
+ return CORD_EMPTY;
} else {
type_t *t = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value);
if (t->tag == AbortType || t->tag == VoidType || t->tag == ReturnType)
code_err(ast, "You can't declare a variable with a ", type_to_str(t), " value");
- CORD val_code = compile_maybe_incref(env, decl->value, t);
- if (t->tag == FunctionType) {
- assert(promote(env, decl->value, &val_code, t, Type(ClosureType, t)));
- t = Type(ClosureType, t);
- }
+ CORD val_code = compile_declared_value(env, ast);
return CORD_all(compile_declaration(t, CORD_cat("_$", name)), " = ", val_code, ";");
}
}
@@ -1792,6 +1788,8 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
auto if_ = Match(ast, If);
ast_t *condition = if_->condition;
if (condition->tag == Declare) {
+ if (Match(condition, Declare)->value == NULL)
+ code_err(condition, "This declaration must have a value");
env_t *truthy_scope = fresh_scope(env);
CORD code = CORD_all("IF_DECLARE(", compile_statement(truthy_scope, condition), ", ");
bind_statement(truthy_scope, condition);
@@ -2474,6 +2472,96 @@ CORD compile_none(type_t *t)
}
}
+CORD compile_empty(type_t *t)
+{
+ if (t == NULL)
+ compiler_err(NULL, NULL, NULL, "I can't compile a value with no type");
+
+ if (t->tag == OptionalType)
+ return compile_none(t);
+
+ if (t == PATH_TYPE) return "NONE_PATH";
+ else if (t == PATH_TYPE_TYPE) return "((OptionalPathType_t){})";
+
+ switch (t->tag) {
+ case BigIntType: return "I(0)";
+ case IntType: {
+ switch (Match(t, IntType)->bits) {
+ case TYPE_IBITS8: return "Int8(0)";
+ case TYPE_IBITS16: return "Int16(0)";
+ case TYPE_IBITS32: return "Int32(0)";
+ case TYPE_IBITS64: return "Int64(0)";
+ default: errx(1, "Invalid integer bit size");
+ }
+ break;
+ }
+ case ByteType: return "((Byte_t)0)";
+ case BoolType: return "((Bool_t)no)";
+ case ArrayType: return "((Array_t){})";
+ case TableType: case SetType: return "((Table_t){})";
+ case TextType: return "Text(\"\")";
+ case CStringType: return "\"\"";
+ case PointerType: {
+ auto ptr = Match(t, PointerType);
+ CORD empty_pointed = compile_empty(ptr->pointed);
+ return empty_pointed == CORD_EMPTY ? CORD_EMPTY : CORD_all(ptr->is_stack ? "stack(" : "heap(", empty_pointed, ")");
+ }
+ case NumType: {
+ return Match(t, NumType)->bits == TYPE_NBITS32 ? "Num32(0.0f)" : "Num64(0.0)" ;
+ }
+ case StructType: {
+ auto struct_ = Match(t, StructType);
+ CORD code = CORD_all("((", compile_type(t), "){");
+ for (arg_t *field = struct_->fields; field; field = field->next) {
+ CORD empty_field = field->default_val
+ ? compile(struct_->env, field->default_val)
+ : compile_empty(field->type);
+ if (empty_field == CORD_EMPTY)
+ return CORD_EMPTY;
+
+ code = CORD_all(code, empty_field);
+ if (field->next)
+ code = CORD_all(code, ", ");
+ }
+ return CORD_all(code, "})");
+ }
+ case EnumType: {
+ auto enum_ = Match(t, EnumType);
+ tag_t *tag = enum_->tags;
+ assert(tag);
+ assert(tag->type);
+ if (Match(tag->type, StructType)->fields)
+ return CORD_all("((", compile_type(t), "){.$tag=", String(tag->tag_value), ", .", tag->name, "=", compile_empty(tag->type), "})");
+ else
+ return CORD_all("((", compile_type(t), "){.$tag=", String(tag->tag_value), "})");
+ }
+ default: return CORD_EMPTY;
+ }
+}
+
+static CORD compile_declared_value(env_t *env, ast_t *declare_ast)
+{
+ auto decl = Match(declare_ast, Declare);
+ type_t *t = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value);
+
+ if (t->tag == AbortType || t->tag == VoidType || t->tag == ReturnType)
+ code_err(declare_ast, "You can't declare a variable with a ", type_to_str(t), " value");
+
+ if (decl->value) {
+ CORD val_code = compile_maybe_incref(env, decl->value, t);
+ if (t->tag == FunctionType) {
+ assert(promote(env, decl->value, &val_code, t, Type(ClosureType, t)));
+ t = Type(ClosureType, t);
+ }
+ return val_code;
+ } else {
+ CORD val_code = compile_empty(t);
+ if (val_code == CORD_EMPTY)
+ code_err(declare_ast, "This type (", type_to_str(t), ") cannot be uninitialized. You must provide a value.");
+ return val_code;
+ }
+}
+
ast_t *add_to_table_comprehension(ast_t *entry, ast_t *subject)
{
auto e = Match(entry, TableEntry);
@@ -3377,6 +3465,8 @@ CORD compile(env_t *env, ast_t *ast)
CORD condition_code;
if (condition->tag == Declare) {
auto decl = Match(condition, Declare);
+ if (decl->value == NULL)
+ code_err(condition, "This declaration must have a value");
type_t *condition_type =
decl->type ? parse_type_ast(env, decl->type)
: get_type(env, Match(condition, Declare)->value);
@@ -4121,17 +4211,9 @@ CORD compile_top_level_code(env_t *env, ast_t *ast)
const char *decl_name = Match(decl->var, Var)->name;
CORD full_name = CORD_all(namespace_prefix(env, env->namespace), decl_name);
type_t *t = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value);
- if (t->tag == AbortType || t->tag == VoidType || t->tag == ReturnType)
- code_err(ast, "You can't declare a variable with a ", type_to_str(t), " value");
-
- CORD val_code = compile_maybe_incref(env, decl->value, t);
- if (t->tag == FunctionType) {
- assert(promote(env, decl->value, &val_code, t, Type(ClosureType, t)));
- t = Type(ClosureType, t);
- }
-
+ CORD val_code = compile_declared_value(env, ast);
bool is_private = decl_name[0] == '_';
- if (is_constant(env, decl->value)) {
+ if ((decl->value && is_constant(env, decl->value)) || (!decl->value && !has_heap_memory(t))) {
set_binding(env, decl_name, t, full_name);
return CORD_all(
is_private ? "static " : CORD_EMPTY,
@@ -4215,17 +4297,9 @@ static void initialize_vars_and_statics(env_t *env, ast_t *ast)
auto decl = Match(stmt->ast, Declare);
const char *decl_name = Match(decl->var, Var)->name;
CORD full_name = CORD_all(namespace_prefix(env, env->namespace), decl_name);
- type_t *t = get_type(env, decl->value);
- if (t->tag == AbortType || t->tag == VoidType || t->tag == ReturnType)
- code_err(stmt->ast, "You can't declare a variable with a ", type_to_str(t), " value");
-
- CORD val_code = compile_maybe_incref(env, decl->value, t);
- if (t->tag == FunctionType) {
- assert(promote(env, decl->value, &val_code, t, Type(ClosureType, t)));
- t = Type(ClosureType, t);
- }
-
- if (!is_constant(env, decl->value)) {
+ type_t *t = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value);
+ CORD val_code = compile_declared_value(env, stmt->ast);
+ if ((decl->value && !is_constant(env, decl->value)) || (!decl->value && has_heap_memory(t))) {
env->code->variable_initializers = CORD_all(
env->code->variable_initializers,
with_source_info(
@@ -4406,7 +4480,7 @@ CORD compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t *a
if (is_private)
return CORD_EMPTY;
- type_t *t = get_type(env, decl->value);
+ type_t *t = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value);
if (t->tag == FunctionType)
t = Type(ClosureType, t);
assert(t->tag != ModuleType);
@@ -4414,7 +4488,7 @@ CORD compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t *a
code_err(ast, "You can't declare a variable with a ", type_to_str(t), " value");
return CORD_all(
- compile_statement_type_header(env, header_path, decl->value),
+ decl->value ? compile_statement_type_header(env, header_path, decl->value) : CORD_EMPTY,
"extern ", compile_declaration(t, CORD_cat(namespace_prefix(env, env->namespace), decl_name)), ";\n");
}
case FunctionDef: {
diff --git a/src/parse.c b/src/parse.c
index 7ba557fb..c76266ee 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -1677,13 +1677,15 @@ PARSER(parse_declaration) {
spaces(&pos);
type_ast_t *type = optional(ctx, &pos, parse_type);
spaces(&pos);
- if (!match(&pos, "=")) return NULL;
- ast_t *val = optional(ctx, &pos, parse_extended_expr);
- if (!val) {
- if (optional(ctx, &pos, parse_use))
- parser_err(ctx, start, pos, "'use' statements are only allowed at the top level of a file");
- else
- parser_err(ctx, pos, eol(pos), "This is not a valid expression");
+ ast_t *val = NULL;
+ if (match(&pos, "=")) {
+ val = optional(ctx, &pos, parse_extended_expr);
+ if (!val) {
+ if (optional(ctx, &pos, parse_use))
+ parser_err(ctx, start, pos, "'use' statements are only allowed at the top level of a file");
+ else
+ parser_err(ctx, pos, eol(pos), "This is not a valid expression");
+ }
}
return NewAST(ctx->file, start, pos, Declare, .var=var, .type=type, .value=val);
}
diff --git a/src/typecheck.c b/src/typecheck.c
index fed02ec6..a869f73e 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -303,10 +303,11 @@ void bind_statement(env_t *env, ast_t *statement)
return;
if (get_binding(env, name))
code_err(decl->var, "A ", type_to_str(get_binding(env, name)->type), " called ", quoted(name), " has already been defined");
- bind_statement(env, decl->value);
+ if (decl->value)
+ bind_statement(env, decl->value);
type_t *type = decl->type ? parse_type_ast(env, decl->type) : get_type(env, decl->value);
if (!type)
- code_err(decl->value, "I couldn't figure out the type of this value");
+ code_err(statement, "I couldn't figure out the type of this value");
if (type->tag == FunctionType)
type = Type(ClosureType, type);
CORD prefix = namespace_prefix(env, env->namespace);
diff --git a/test/arrays.tm b/test/arrays.tm
index f2ed2c7a..8122106c 100644
--- a/test/arrays.tm
+++ b/test/arrays.tm
@@ -4,6 +4,10 @@ func main()
= []
do
+ >> nums : [Num32]
+ = []
+
+ do
>> arr := [10, 20, 30]
= [10, 20, 30]
@@ -104,7 +108,7 @@ func main()
>> heap := @[(i * 1337) mod 37 for i in 10]
>> heap.heapify()
>> heap
- heap_order : @[Int] = @[]
+ heap_order : @[Int]
repeat
heap_order.insert(heap.heap_pop() or stop)
>> heap_order[] == heap_order.sorted()
diff --git a/test/defer.tm b/test/defer.tm
index e5033075..6c204851 100644
--- a/test/defer.tm
+++ b/test/defer.tm
@@ -1,6 +1,6 @@
func main()
x := 123
- nums : @[Int] = @[]
+ nums : @[Int]
do
defer
nums.insert(x)
diff --git a/test/import.tm b/test/import.tm
index a6a6fa16..0686190b 100644
--- a/test/import.tm
+++ b/test/import.tm
@@ -8,11 +8,11 @@ func returns_imported_type(->ImportedType)
return get_value() # Imported from ./use_import.tm
func main()
- >> empty : [vectors.Vec2] = []
+ >> empty : [vectors.Vec2]
>> returns_vec()
= Vec2(x=1, y=2)
- >> imported : [ImportedType] = []
+ >> imported : [ImportedType]
>> returns_imported_type()
= ImportedType("Hello")
diff --git a/test/iterators.tm b/test/iterators.tm
index 1816fd7a..08382cff 100644
--- a/test/iterators.tm
+++ b/test/iterators.tm
@@ -25,7 +25,7 @@ func main()
= ["AB", "BC", "CD"]
do
- result : @[Text] = @[]
+ result : @[Text]
for foo in pairwise(values)
result.insert("$(foo.x)$(foo.y)")
>> result[]
diff --git a/test/reductions.tm b/test/reductions.tm
index 2666e1a9..3ec2ef5e 100644
--- a/test/reductions.tm
+++ b/test/reductions.tm
@@ -4,7 +4,7 @@ func main()
>> (+: [10, 20, 30])
= 60?
- >> empty_ints : [Int] = []
+ >> empty_ints : [Int]
>> (+: empty_ints)
= none