Allow uninitialized variables when there's a sensible empty value
(defaults to empty/zero value)
This commit is contained in:
parent
bc93dea818
commit
1d2e55f53d
@ -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")
|
||||
|
@ -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) }
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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}/, " ")
|
||||
|
@ -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
|
||||
|
@ -3,7 +3,7 @@ use <stdio.h>
|
||||
|
||||
timestamp_format := CString("%F %T")
|
||||
|
||||
logfiles : @|Path| = @||
|
||||
logfiles : @|Path|
|
||||
|
||||
func _timestamp(->Text)
|
||||
c_str := inline C:CString {
|
||||
|
@ -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]
|
||||
|
@ -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 ||
|
||||
|
@ -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)
|
||||
|
154
src/compile.c
154
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: {
|
||||
|
16
src/parse.c
16
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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -3,6 +3,10 @@ func main()
|
||||
>> nums : [Num32] = []
|
||||
= []
|
||||
|
||||
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()
|
||||
|
@ -1,6 +1,6 @@
|
||||
func main()
|
||||
x := 123
|
||||
nums : @[Int] = @[]
|
||||
nums : @[Int]
|
||||
do
|
||||
defer
|
||||
nums.insert(x)
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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[]
|
||||
|
@ -4,7 +4,7 @@ func main()
|
||||
>> (+: [10, 20, 30])
|
||||
= 60?
|
||||
|
||||
>> empty_ints : [Int] = []
|
||||
>> empty_ints : [Int]
|
||||
>> (+: empty_ints)
|
||||
= none
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user