diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-04-06 14:20:18 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-04-06 14:20:18 -0400 |
| commit | 2bb2ff871fa1761478442bec5f6a32c9428360a1 (patch) | |
| tree | 9b73df7a0c50c02353ae7bca7c2cd54788ef0077 /src | |
| parent | 59845e610f2c90474f34079d27b5f1e07071ded4 (diff) | |
Change method calls to use `foo.baz()` instead of `foo:baz()`
Diffstat (limited to 'src')
| -rw-r--r-- | src/compile.c | 22 | ||||
| -rw-r--r-- | src/parse.c | 10 | ||||
| -rw-r--r-- | src/stdlib/tables.c | 10 | ||||
| -rw-r--r-- | src/tomo.c | 2 | ||||
| -rw-r--r-- | src/typecheck.c | 13 |
5 files changed, 40 insertions, 17 deletions
diff --git a/src/compile.c b/src/compile.c index a4f5b3ec..46a0e607 100644 --- a/src/compile.c +++ b/src/compile.c @@ -1468,7 +1468,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) // If we're iterating over a comprehension, that's actually just doing // one loop, we don't need to compile the comprehension as an array // comprehension. This is a common case for reducers like `(+: i*2 for i in 5)` - // or `(and) x:is_good() for x in xs` + // or `(and) x.is_good() for x in xs` if (for_->iter->tag == Comprehension) { auto comp = Match(for_->iter, Comprehension); ast_t *body = for_->body; @@ -1552,7 +1552,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast) stop); } else if (for_->iter->tag == MethodCall && streq(Match(for_->iter, MethodCall)->name, "onward") && get_type(env, Match(for_->iter, MethodCall)->self)->tag == BigIntType) { - // Special case for Int:onward() + // Special case for Int.onward() arg_ast_t *args = Match(for_->iter, MethodCall)->args; arg_t *arg_spec = new(arg_t, .name="step", .type=INT_TYPE, .default_val=FakeAST(Int, .str="1"), .next=NULL); CORD step = compile_arguments(env, for_->iter, arg_spec, args); @@ -1933,7 +1933,7 @@ CORD compile_to_pointer_depth(env_t *env, ast_t *ast, int64_t target_depth, bool ++depth; // Passing a literal value won't trigger an incref, because it's ephemeral, - // e.g. [10, 20]:reversed() + // e.g. [10, 20].reversed() if (t->tag != PointerType && needs_incref && !can_be_mutated(env, ast)) needs_incref = false; @@ -2001,7 +2001,7 @@ CORD compile_to_type(env_t *env, ast_t *ast, type_t *t) // should be from what we know the specific type of the return value is, // but it requires a bit of special logic. // For example: - // x : [Int?] = [none]:sorted() + // x : [Int?] = [none].sorted() // Here, we know that `[none]` is `[Int?]`, but we need to thread that // information through the compiler using an `ExplicitlyTyped` node. if (ast->tag == MethodCall) { @@ -2924,7 +2924,7 @@ CORD compile(env_t *env, ast_t *ast) if (streq(call->name, "serialized")) { if (call->args) - code_err(ast, ":serialized() doesn't take any arguments"); + code_err(ast, ".serialized() doesn't take any arguments"); return CORD_all("generic_serialize((", compile_declaration(self_t, "[1]"), "){", compile(env, call->self), "}, ", compile_type_info(self_t), ")"); } @@ -2934,6 +2934,18 @@ CORD compile(env_t *env, ast_t *ast) for (; self_value_t->tag == PointerType; self_value_t = Match(self_value_t, PointerType)->pointed) pointer_depth += 1; + if (self_value_t->tag == TypeInfoType || self_value_t->tag == ModuleType) { + return compile(env, WrapAST(ast, FunctionCall, .fn=WrapAST(call->self, FieldAccess, .fielded=call->self, .field=call->name), + .args=call->args)); + } + + type_t *field_type = get_field_type(self_value_t, call->name); + if (field_type && field_type->tag == ClosureType) + field_type = Match(field_type, ClosureType)->fn; + if (field_type && field_type->tag == FunctionType) + return compile(env, WrapAST(ast, FunctionCall, .fn=WrapAST(call->self, FieldAccess, .fielded=call->self, .field=call->name), + .args=call->args)); + CORD self = compile(env, call->self); #define EXPECT_POINTER(article, name) do { \ diff --git a/src/parse.c b/src/parse.c index fa021e28..d686bb6d 100644 --- a/src/parse.c +++ b/src/parse.c @@ -847,8 +847,8 @@ PARSER(parse_reduction) { ast_t *new_term; progress = (false || (new_term=parse_index_suffix(ctx, key)) - || (new_term=parse_field_suffix(ctx, key)) || (new_term=parse_method_call_suffix(ctx, key)) + || (new_term=parse_field_suffix(ctx, key)) || (new_term=parse_fncall_suffix(ctx, key)) || (new_term=parse_optional_suffix(ctx, key)) || (new_term=parse_non_optional_suffix(ctx, key)) @@ -1095,6 +1095,7 @@ PARSER(parse_heap_alloc) { ast_t *new_term; if ((new_term=parse_index_suffix(ctx, val)) || (new_term=parse_fncall_suffix(ctx, val)) + || (new_term=parse_method_call_suffix(ctx, val)) || (new_term=parse_field_suffix(ctx, val))) { val = new_term; } else break; @@ -1121,6 +1122,7 @@ PARSER(parse_stack_reference) { ast_t *new_term; if ((new_term=parse_index_suffix(ctx, val)) || (new_term=parse_fncall_suffix(ctx, val)) + || (new_term=parse_method_call_suffix(ctx, val)) || (new_term=parse_field_suffix(ctx, val))) { val = new_term; } else break; @@ -1462,8 +1464,8 @@ PARSER(parse_term) { ast_t *new_term; progress = (false || (new_term=parse_index_suffix(ctx, term)) - || (new_term=parse_field_suffix(ctx, term)) || (new_term=parse_method_call_suffix(ctx, term)) + || (new_term=parse_field_suffix(ctx, term)) || (new_term=parse_fncall_suffix(ctx, term)) || (new_term=parse_optional_suffix(ctx, term)) || (new_term=parse_non_optional_suffix(ctx, term)) @@ -1479,7 +1481,7 @@ ast_t *parse_method_call_suffix(parse_ctx_t *ctx, ast_t *self) { const char *start = self->start; const char *pos = self->end; - if (!match(&pos, ":")) return NULL; + if (!match(&pos, ".")) return NULL; if (*pos == ' ') return NULL; const char *fn = get_id(&pos); if (!fn) return NULL; @@ -1622,8 +1624,8 @@ static ast_t *parse_infix_expr(parse_ctx_t *ctx, const char *pos, int min_tightn ast_t *new_term; progress = (false || (new_term=parse_index_suffix(ctx, key)) - || (new_term=parse_field_suffix(ctx, key)) || (new_term=parse_method_call_suffix(ctx, key)) + || (new_term=parse_field_suffix(ctx, key)) || (new_term=parse_fncall_suffix(ctx, key)) || (new_term=parse_optional_suffix(ctx, key)) || (new_term=parse_non_optional_suffix(ctx, key)) diff --git a/src/stdlib/tables.c b/src/stdlib/tables.c index dfa35236..58c1b2e4 100644 --- a/src/stdlib/tables.c +++ b/src/stdlib/tables.c @@ -446,10 +446,10 @@ PUREFUNC public int32_t Table$compare(const void *vx, const void *vy, const Type // Table comparison rules: // - If two tables have different keys, then compare as if comparing a // sorted array of the keys of the two tables: - // `x.keys:sorted() <> y.keys:sorted()` + // `x.keys.sorted() <> y.keys.sorted()` // - Otherwise, compare as if comparing arrays of values for the sorted key // arrays: - // `[x[k] for k in x.keys:sorted()] <> [y[k] for k in y.keys:sorted()]` + // `[x[k] for k in x.keys.sorted()] <> [y[k] for k in y.keys.sorted()]` // // We can do this in _linear_ time if we find the smallest `k` such that // `x[k] != y[k]`, as well as the largest key in `x` and `y`. @@ -637,7 +637,7 @@ public Table_t Table$from_entries(Array_t entries, const TypeInfo_t *type) // Overlap is "set intersection" in formal terms public Table_t Table$overlap(Table_t a, Table_t b, const TypeInfo_t *type) { - // Return a table such that t[k]==a[k] for all k such that a:has(k), b:has(k), and a[k]==b[k] + // Return a table such that t[k]==a[k] for all k such that a.has(k), b.has(k), and a[k]==b[k] Table_t result = {}; const size_t offset = value_offset(type); for (int64_t i = 0; i < Table$length(a); i++) { @@ -659,7 +659,7 @@ public Table_t Table$overlap(Table_t a, Table_t b, const TypeInfo_t *type) // With is "set union" in formal terms public Table_t Table$with(Table_t a, Table_t b, const TypeInfo_t *type) { - // return a table such that t[k]==b[k] for all k such that b:has(k), and t[k]==a[k] for all k such that a:has(k) and not b:has(k) + // return a table such that t[k]==b[k] for all k such that b.has(k), and t[k]==a[k] for all k such that a.has(k) and not b.has(k) Table_t result = {}; const size_t offset = value_offset(type); for (int64_t i = 0; i < Table$length(a); i++) { @@ -684,7 +684,7 @@ public Table_t Table$with(Table_t a, Table_t b, const TypeInfo_t *type) // Without is "set difference" in formal terms public Table_t Table$without(Table_t a, Table_t b, const TypeInfo_t *type) { - // Return a table such that t[k]==a[k] for all k such that not b:has(k) or b[k] != a[k] + // Return a table such that t[k]==a[k] for all k such that not b.has(k) or b[k] != a[k] Table_t result = {}; const size_t offset = value_offset(type); for (int64_t i = 0; i < Table$length(a); i++) { @@ -241,8 +241,6 @@ int main(int argc, char *argv[]) if (files.length < 1) print_err("No file specified!"); - else if (files.length != 1) - print_err("Too many files specified!"); quiet = !verbose; diff --git a/src/typecheck.c b/src/typecheck.c index c5243195..21e02460 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -550,7 +550,7 @@ type_t *get_method_type(env_t *env, ast_t *self, const char *name) { binding_t *b = get_namespace_binding(env, self, name); if (!b || !b->type) - code_err(self, "No such method: ", type_to_str(get_type(env, self)), ":", name, "(...)"); + code_err(self, "No such method: ", type_to_str(get_type(env, self)), ".", name, "(...)"); return b->type; } @@ -895,6 +895,12 @@ type_t *get_type(env_t *env, ast_t *ast) type_t *self_value_t = get_type(env, call->self); if (!self_value_t) code_err(call->self, "Couldn't get the type of this value"); self_value_t = value_type(self_value_t); + + if (self_value_t->tag == TypeInfoType || self_value_t->tag == ModuleType) { + return get_type(env, WrapAST(ast, FunctionCall, .fn=WrapAST(call->self, FieldAccess, .fielded=call->self, .field=call->name), + .args=call->args)); + } + switch (self_value_t->tag) { case ArrayType: { type_t *item_type = Match(self_value_t, ArrayType)->item_type; @@ -952,6 +958,11 @@ type_t *get_type(env_t *env, ast_t *ast) code_err(ast, "There is no '", call->name, "' method for ", type_to_str(self_value_t), " tables"); } default: { + type_t *field_type = get_field_type(self_value_t, call->name); + if (field_type && field_type->tag == ClosureType) + field_type = Match(field_type, ClosureType)->fn; + if (field_type && field_type->tag == FunctionType) + return Match(field_type, FunctionType)->ret; type_t *fn_type_t = get_method_type(env, call->self, call->name); if (!fn_type_t) code_err(ast, "No such method!"); |
