mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-07 22:55:00 +00:00
Merge pull request #7859 from roc-lang/external-decls
Single module `import` `exposes` `as`
This commit is contained in:
commit
078ac7c512
62 changed files with 2268 additions and 363 deletions
|
@ -1,6 +1,7 @@
|
|||
const std = @import("std");
|
||||
const base = @import("../base.zig");
|
||||
const parse = @import("parse.zig");
|
||||
const tokenize = @import("parse/tokenize.zig");
|
||||
const collections = @import("../collections.zig");
|
||||
const types = @import("../types/types.zig");
|
||||
|
||||
|
@ -9,6 +10,7 @@ const Scope = @import("./canonicalize/Scope.zig");
|
|||
const Node = @import("./canonicalize/Node.zig");
|
||||
|
||||
const AST = parse.AST;
|
||||
const Token = tokenize.Token;
|
||||
|
||||
can_ir: *CIR,
|
||||
parse_ir: *AST,
|
||||
|
@ -260,12 +262,8 @@ pub fn canonicalize_file(
|
|||
for (self.parse_ir.store.statementSlice(file.statements)) |stmt_id| {
|
||||
const stmt = self.parse_ir.store.getStatement(stmt_id);
|
||||
switch (stmt) {
|
||||
.import => |_| {
|
||||
const feature = self.can_ir.env.strings.insert(self.can_ir.env.gpa, "top-level import");
|
||||
self.can_ir.pushDiagnostic(CIR.Diagnostic{ .not_implemented = .{
|
||||
.feature = feature,
|
||||
.region = Region.zero(),
|
||||
} });
|
||||
.import => |import_stmt| {
|
||||
_ = self.canonicalizeImportStatement(import_stmt);
|
||||
},
|
||||
.decl => |decl| {
|
||||
const def_idx = self.canonicalize_decl(decl);
|
||||
|
@ -490,6 +488,205 @@ fn bringIngestedFileIntoScope(
|
|||
}
|
||||
}
|
||||
|
||||
/// Canonicalize an import statement, handling both top-level file imports and statement imports
|
||||
fn canonicalizeImportStatement(
|
||||
self: *Self,
|
||||
import_stmt: @TypeOf(@as(AST.Statement, undefined).import),
|
||||
) ?CIR.Statement.Idx {
|
||||
// 1. Reconstruct the full module name (e.g., "json.Json")
|
||||
const module_name = blk: {
|
||||
if (self.parse_ir.tokens.resolveIdentifier(import_stmt.module_name_tok) == null) {
|
||||
const region = self.parse_ir.tokenizedRegionToRegion(import_stmt.region);
|
||||
const feature = self.can_ir.env.strings.insert(self.can_ir.env.gpa, "resolve import module name token");
|
||||
self.can_ir.pushDiagnostic(CIR.Diagnostic{ .not_implemented = .{
|
||||
.feature = feature,
|
||||
.region = region,
|
||||
} });
|
||||
return null;
|
||||
}
|
||||
|
||||
if (import_stmt.qualifier_tok) |qualifier_tok| {
|
||||
if (self.parse_ir.tokens.resolveIdentifier(qualifier_tok) == null) {
|
||||
const region = self.parse_ir.tokenizedRegionToRegion(import_stmt.region);
|
||||
const feature = self.can_ir.env.strings.insert(self.can_ir.env.gpa, "resolve import qualifier token");
|
||||
self.can_ir.pushDiagnostic(CIR.Diagnostic{ .not_implemented = .{
|
||||
.feature = feature,
|
||||
.region = region,
|
||||
} });
|
||||
return null;
|
||||
}
|
||||
|
||||
// Slice from original source to get "qualifier.ModuleName"
|
||||
const qualifier_region = self.parse_ir.tokens.resolve(qualifier_tok);
|
||||
const module_region = self.parse_ir.tokens.resolve(import_stmt.module_name_tok);
|
||||
const full_name = self.parse_ir.source[qualifier_region.start.offset..module_region.end.offset];
|
||||
break :blk self.can_ir.env.idents.insert(self.can_ir.env.gpa, base.Ident.for_text(full_name), Region.zero());
|
||||
} else {
|
||||
// No qualifier, just use the module name directly
|
||||
break :blk self.parse_ir.tokens.resolveIdentifier(import_stmt.module_name_tok).?;
|
||||
}
|
||||
};
|
||||
|
||||
// 2. Determine the alias (either explicit or default to last part)
|
||||
const alias = self.resolveModuleAlias(import_stmt.alias_tok, module_name) orelse return null;
|
||||
|
||||
// 3. Add to scope: alias -> module_name mapping
|
||||
self.scopeIntroduceModuleAlias(alias, module_name);
|
||||
|
||||
// 4. Convert exposed items and introduce them into scope
|
||||
const cir_exposes = self.convertASTExposesToCIR(import_stmt.exposes);
|
||||
self.introduceExposedItemsIntoScope(cir_exposes, module_name);
|
||||
|
||||
// 5. Create CIR import statement
|
||||
const cir_import = CIR.Statement{
|
||||
.import = .{
|
||||
.module_name_tok = module_name,
|
||||
.qualifier_tok = if (import_stmt.qualifier_tok) |q_tok| self.parse_ir.tokens.resolveIdentifier(q_tok) else null,
|
||||
.alias_tok = if (import_stmt.alias_tok) |a_tok| self.parse_ir.tokens.resolveIdentifier(a_tok) else null,
|
||||
.exposes = cir_exposes,
|
||||
.region = self.parse_ir.tokenizedRegionToRegion(import_stmt.region),
|
||||
},
|
||||
};
|
||||
|
||||
const import_idx = self.can_ir.store.addStatement(cir_import);
|
||||
self.can_ir.store.addScratchStatement(import_idx);
|
||||
return import_idx;
|
||||
}
|
||||
|
||||
/// Resolve the module alias name from either explicit alias or module name
|
||||
fn resolveModuleAlias(
|
||||
self: *Self,
|
||||
alias_tok: ?Token.Idx,
|
||||
module_name: Ident.Idx,
|
||||
) ?Ident.Idx {
|
||||
if (alias_tok) |alias_token| {
|
||||
return self.parse_ir.tokens.resolveIdentifier(alias_token);
|
||||
} else {
|
||||
// Extract last part from module name - e.g., "Json" from "json.Json"
|
||||
return self.extractModuleName(module_name);
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a qualified name by combining module and field names (e.g., "json.Json.utf8")
|
||||
fn createQualifiedName(
|
||||
self: *Self,
|
||||
module_name: Ident.Idx,
|
||||
field_name: Ident.Idx,
|
||||
) Ident.Idx {
|
||||
const module_text = self.can_ir.env.idents.getText(module_name);
|
||||
const field_text = self.can_ir.env.idents.getText(field_name);
|
||||
|
||||
// Allocate space for "module.field" - this case still needs allocation since we're combining
|
||||
// module name from import with field name from usage site
|
||||
const qualified_text = std.fmt.allocPrint(self.can_ir.env.gpa, "{s}.{s}", .{ module_text, field_text }) catch |err| exitOnOom(err);
|
||||
defer self.can_ir.env.gpa.free(qualified_text);
|
||||
|
||||
return self.can_ir.env.idents.insert(self.can_ir.env.gpa, base.Ident.for_text(qualified_text), Region.zero());
|
||||
}
|
||||
|
||||
/// Create an external declaration for a qualified name
|
||||
fn createExternalDeclaration(
|
||||
self: *Self,
|
||||
qualified_name: Ident.Idx,
|
||||
module_name: Ident.Idx,
|
||||
local_name: Ident.Idx,
|
||||
kind: CIR.ExternalDecl.kind,
|
||||
region: Region,
|
||||
) CIR.ExternalDecl.Idx {
|
||||
const external_decl = CIR.ExternalDecl{
|
||||
.qualified_name = qualified_name,
|
||||
.module_name = module_name,
|
||||
.local_name = local_name,
|
||||
.type_var = self.can_ir.pushFreshTypeVar(@enumFromInt(0), region),
|
||||
.kind = kind,
|
||||
.region = region,
|
||||
};
|
||||
|
||||
return self.can_ir.pushExternalDecl(external_decl);
|
||||
}
|
||||
|
||||
/// Convert AST exposed items to CIR exposed items
|
||||
fn convertASTExposesToCIR(
|
||||
self: *Self,
|
||||
ast_exposes: AST.ExposedItem.Span,
|
||||
) CIR.ExposedItem.Span {
|
||||
const scratch_start = self.can_ir.store.scratchExposedItemTop();
|
||||
|
||||
const ast_exposed_slice = self.parse_ir.store.exposedItemSlice(ast_exposes);
|
||||
for (ast_exposed_slice) |ast_exposed_idx| {
|
||||
const ast_exposed = self.parse_ir.store.getExposedItem(ast_exposed_idx);
|
||||
|
||||
// Convert AST exposed item to CIR exposed item
|
||||
const cir_exposed = convert_item: {
|
||||
// Extract identifier token and alias token
|
||||
const ident_token, const alias_token, const is_wildcard = switch (ast_exposed) {
|
||||
.lower_ident => |ident| .{ ident.ident, ident.as, false },
|
||||
.upper_ident => |ident| .{ ident.ident, ident.as, false },
|
||||
.upper_ident_star => |star_ident| .{ star_ident.ident, null, true },
|
||||
};
|
||||
|
||||
// Resolve the main identifier name
|
||||
const name = resolve_ident: {
|
||||
if (self.parse_ir.tokens.resolveIdentifier(ident_token)) |resolved| {
|
||||
break :resolve_ident resolved;
|
||||
} else {
|
||||
break :resolve_ident self.can_ir.env.idents.insert(self.can_ir.env.gpa, base.Ident.for_text("unknown"), base.Region.zero());
|
||||
}
|
||||
};
|
||||
|
||||
// Resolve the alias if present
|
||||
const alias = resolve_alias: {
|
||||
if (alias_token) |as_token| {
|
||||
if (self.parse_ir.tokens.resolveIdentifier(as_token)) |resolved| {
|
||||
break :resolve_alias resolved;
|
||||
} else {
|
||||
break :resolve_alias self.can_ir.env.idents.insert(self.can_ir.env.gpa, base.Ident.for_text("unknown"), base.Region.zero());
|
||||
}
|
||||
} else {
|
||||
break :resolve_alias null;
|
||||
}
|
||||
};
|
||||
|
||||
break :convert_item CIR.ExposedItem{
|
||||
.name = name,
|
||||
.alias = alias,
|
||||
.is_wildcard = is_wildcard,
|
||||
};
|
||||
};
|
||||
|
||||
const cir_exposed_idx = self.can_ir.store.addExposedItem(cir_exposed);
|
||||
self.can_ir.store.addScratchExposedItem(cir_exposed_idx);
|
||||
}
|
||||
|
||||
return self.can_ir.store.exposedItemSpanFrom(scratch_start);
|
||||
}
|
||||
|
||||
/// Introduce converted exposed items into scope for identifier resolution
|
||||
fn introduceExposedItemsIntoScope(
|
||||
self: *Self,
|
||||
exposed_items_span: CIR.ExposedItem.Span,
|
||||
module_name: Ident.Idx,
|
||||
) void {
|
||||
const exposed_items_slice = self.can_ir.store.sliceExposedItems(exposed_items_span);
|
||||
|
||||
for (exposed_items_slice) |exposed_item_idx| {
|
||||
const exposed_item = self.can_ir.store.getExposedItem(exposed_item_idx);
|
||||
|
||||
// Use the alias if provided, otherwise use the original name for the local lookup
|
||||
const item_name = exposed_item.alias orelse exposed_item.name;
|
||||
|
||||
// Create the exposed item info with module name and original name
|
||||
const item_info = Scope.ExposedItemInfo{
|
||||
.module_name = module_name,
|
||||
.original_name = exposed_item.name, // Always use the original name for module lookup
|
||||
};
|
||||
|
||||
// Introduce the exposed item into scope
|
||||
// This allows `decode` to resolve to `json.Json.decode`
|
||||
self.scopeIntroduceExposedItem(item_name, item_info);
|
||||
}
|
||||
}
|
||||
|
||||
fn canonicalize_decl(
|
||||
self: *Self,
|
||||
decl: AST.Statement.Decl,
|
||||
|
@ -601,6 +798,43 @@ pub fn canonicalize_expr(
|
|||
.ident => |e| {
|
||||
const region = self.parse_ir.tokenizedRegionToRegion(e.region);
|
||||
if (self.parse_ir.tokens.resolveIdentifier(e.token)) |ident| {
|
||||
// Check if this is a module-qualified identifier
|
||||
if (e.qualifier) |qualifier_tok| {
|
||||
if (self.parse_ir.tokens.resolveIdentifier(qualifier_tok)) |module_alias| {
|
||||
// Check if this is a module alias
|
||||
if (self.scopeLookupModule(module_alias)) |module_name| {
|
||||
// This is a module-qualified lookup
|
||||
// Create qualified name for external declaration
|
||||
const module_text = self.can_ir.env.idents.getText(module_name);
|
||||
const field_text = self.can_ir.env.idents.getText(ident);
|
||||
|
||||
// Allocate space for qualified name
|
||||
const qualified_text = std.fmt.allocPrint(self.can_ir.env.gpa, "{s}.{s}", .{ module_text, field_text }) catch |err| collections.utils.exitOnOom(err);
|
||||
defer self.can_ir.env.gpa.free(qualified_text);
|
||||
|
||||
const qualified_name = self.can_ir.env.idents.insert(self.can_ir.env.gpa, base.Ident.for_text(qualified_text), Region.zero());
|
||||
|
||||
// Create external declaration
|
||||
const external_decl = CIR.ExternalDecl{
|
||||
.qualified_name = qualified_name,
|
||||
.module_name = module_name,
|
||||
.local_name = ident,
|
||||
.type_var = self.can_ir.pushFreshTypeVar(@enumFromInt(0), region),
|
||||
.kind = .value,
|
||||
.region = region,
|
||||
};
|
||||
|
||||
const external_idx = self.can_ir.pushExternalDecl(external_decl);
|
||||
|
||||
// Create lookup expression for external declaration
|
||||
const expr_idx = self.can_ir.store.addExpr(CIR.Expr{ .lookup = .{ .external = external_idx } });
|
||||
_ = self.can_ir.setTypeVarAtExpr(expr_idx, Content{ .flex_var = null });
|
||||
return expr_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not a module-qualified lookup, or qualifier not found, proceed with normal lookup
|
||||
switch (self.scopeLookup(&self.can_ir.env.idents, .ident, ident)) {
|
||||
.found => |pattern_idx| {
|
||||
// Mark this pattern as used for unused variable checking
|
||||
|
@ -611,15 +845,38 @@ pub fn canonicalize_expr(
|
|||
|
||||
// We found the ident in scope, lookup to reference the pattern
|
||||
const expr_idx =
|
||||
self.can_ir.store.addExpr(CIR.Expr{ .lookup = .{
|
||||
self.can_ir.store.addExpr(CIR.Expr{ .lookup = .{ .local = .{
|
||||
.pattern_idx = pattern_idx,
|
||||
.region = region,
|
||||
} });
|
||||
} } });
|
||||
_ = self.can_ir.setTypeVarAtExpr(expr_idx, Content{ .flex_var = null });
|
||||
return expr_idx;
|
||||
},
|
||||
.not_found => {
|
||||
// We did not find the ident in scope
|
||||
// Check if this identifier is an exposed item from an import
|
||||
if (self.scopeLookupExposedItem(ident)) |exposed_info| {
|
||||
// Create qualified name using the original name, not the alias
|
||||
const qualified_name = self.createQualifiedName(exposed_info.module_name, exposed_info.original_name);
|
||||
|
||||
// Create external declaration for the exposed item
|
||||
const external_decl = CIR.ExternalDecl{
|
||||
.qualified_name = qualified_name,
|
||||
.module_name = exposed_info.module_name,
|
||||
.local_name = ident,
|
||||
.type_var = self.can_ir.pushFreshTypeVar(@enumFromInt(0), region),
|
||||
.kind = .value,
|
||||
.region = region,
|
||||
};
|
||||
|
||||
const external_idx = self.can_ir.pushExternalDecl(external_decl);
|
||||
|
||||
// Create lookup expression for external declaration
|
||||
const expr_idx = self.can_ir.store.addExpr(CIR.Expr{ .lookup = .{ .external = external_idx } });
|
||||
_ = self.can_ir.setTypeVarAtExpr(expr_idx, Content{ .flex_var = null });
|
||||
return expr_idx;
|
||||
}
|
||||
|
||||
// We did not find the ident in scope or as an exposed item
|
||||
return self.can_ir.pushMalformed(CIR.Expr.Idx, CIR.Diagnostic{ .ident_not_in_scope = .{
|
||||
.ident = ident,
|
||||
.region = region,
|
||||
|
@ -963,84 +1220,13 @@ pub fn canonicalize_expr(
|
|||
return expr_idx;
|
||||
},
|
||||
.field_access => |field_access| {
|
||||
// Canonicalize the receiver (left side of the dot)
|
||||
const receiver_idx = blk: {
|
||||
if (self.canonicalize_expr(field_access.left)) |idx| {
|
||||
break :blk idx;
|
||||
} else {
|
||||
// Failed to canonicalize receiver, return malformed
|
||||
const region = self.parse_ir.tokenizedRegionToRegion(field_access.region);
|
||||
return self.can_ir.pushMalformed(CIR.Expr.Idx, CIR.Diagnostic{ .expr_not_canonicalized = .{
|
||||
.region = region,
|
||||
} });
|
||||
}
|
||||
};
|
||||
|
||||
// Parse the right side - this could be just a field name or a method call
|
||||
const right_expr = self.parse_ir.store.getExpr(field_access.right);
|
||||
|
||||
var field_name: Ident.Idx = undefined;
|
||||
var args: ?CIR.Expr.Span = null;
|
||||
|
||||
switch (right_expr) {
|
||||
.apply => |apply| {
|
||||
// This is a method call like .map(fn)
|
||||
const method_expr = self.parse_ir.store.getExpr(apply.@"fn");
|
||||
switch (method_expr) {
|
||||
.ident => |ident| {
|
||||
// Get the method name
|
||||
if (self.parse_ir.tokens.resolveIdentifier(ident.token)) |ident_idx| {
|
||||
field_name = ident_idx;
|
||||
} else {
|
||||
// Fallback for malformed identifiers
|
||||
field_name = self.can_ir.env.idents.insert(self.can_ir.env.gpa, base.Ident.for_text("unknown"), Region.zero());
|
||||
}
|
||||
},
|
||||
else => {
|
||||
// Fallback to a generic name
|
||||
field_name = self.can_ir.env.idents.insert(self.can_ir.env.gpa, base.Ident.for_text("unknown"), Region.zero());
|
||||
},
|
||||
}
|
||||
|
||||
// Canonicalize the arguments using scratch system
|
||||
const scratch_top = self.can_ir.store.scratchExprTop();
|
||||
for (self.parse_ir.store.exprSlice(apply.args)) |arg_idx| {
|
||||
if (self.canonicalize_expr(arg_idx)) |canonicalized| {
|
||||
self.can_ir.store.addScratchExpr(canonicalized);
|
||||
} else {
|
||||
self.can_ir.store.clearScratchExprsFrom(scratch_top);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
args = self.can_ir.store.exprSpanFrom(scratch_top);
|
||||
},
|
||||
.ident => |ident| {
|
||||
// Get the field name
|
||||
if (self.parse_ir.tokens.resolveIdentifier(ident.token)) |ident_idx| {
|
||||
field_name = ident_idx;
|
||||
} else {
|
||||
// Fallback for malformed identifiers
|
||||
field_name = self.can_ir.env.idents.insert(self.can_ir.env.gpa, base.Ident.for_text("unknown"), Region.zero());
|
||||
}
|
||||
},
|
||||
else => {
|
||||
// Fallback
|
||||
field_name = self.can_ir.env.idents.insert(self.can_ir.env.gpa, base.Ident.for_text("unknown"), Region.zero());
|
||||
},
|
||||
// Try module-qualified lookup first (e.g., Json.utf8)
|
||||
if (self.tryModuleQualifiedLookup(field_access)) |expr_idx| {
|
||||
return expr_idx;
|
||||
}
|
||||
|
||||
const dot_access_expr = CIR.Expr{
|
||||
.dot_access = .{
|
||||
.receiver = receiver_idx,
|
||||
.field_name = field_name,
|
||||
.args = args,
|
||||
.region = self.parse_ir.tokenizedRegionToRegion(field_access.region),
|
||||
},
|
||||
};
|
||||
|
||||
const expr_idx = self.can_ir.store.addExpr(dot_access_expr);
|
||||
_ = self.can_ir.setTypeVarAtExpr(expr_idx, Content{ .flex_var = null });
|
||||
return expr_idx;
|
||||
// Regular field access canonicalization
|
||||
return self.canonicalizeRegularFieldAccess(field_access);
|
||||
},
|
||||
.local_dispatch => |_| {
|
||||
const feature = self.can_ir.env.strings.insert(self.can_ir.env.gpa, "canonicalize local_dispatch expression");
|
||||
|
@ -2134,6 +2320,20 @@ fn canonicalize_statement(self: *Self, stmt_idx: AST.Statement.Idx) ?CIR.Expr.Id
|
|||
_ = self.can_ir.setTypeVarAtExpr(unit_expr, Content{ .flex_var = null });
|
||||
return unit_expr;
|
||||
},
|
||||
.import => |import_stmt| {
|
||||
_ = self.canonicalizeImportStatement(import_stmt);
|
||||
|
||||
// Import statements don't produce runtime values, so return a unit expression
|
||||
const region = self.parse_ir.tokenizedRegionToRegion(import_stmt.region);
|
||||
const empty_span = CIR.Expr.Span{ .span = base.DataSpan{ .start = 0, .len = 0 } };
|
||||
const unit_expr = self.can_ir.store.addExpr(CIR.Expr{ .tuple = .{
|
||||
.tuple_var = self.can_ir.pushFreshTypeVar(@enumFromInt(0), region),
|
||||
.elems = empty_span,
|
||||
.region = region,
|
||||
} });
|
||||
_ = self.can_ir.setTypeVarAtExpr(unit_expr, Content{ .flex_var = null });
|
||||
return unit_expr;
|
||||
},
|
||||
else => {
|
||||
// Other statement types not yet implemented
|
||||
const feature = self.can_ir.env.strings.insert(self.can_ir.env.gpa, "statement type in block");
|
||||
|
@ -2625,6 +2825,176 @@ fn scopeLookupTypeDecl(self: *const Self, name_ident: Ident.Idx) ?CIR.Statement.
|
|||
return null;
|
||||
}
|
||||
|
||||
/// Look up a module alias in the scope hierarchy
|
||||
fn scopeLookupModule(self: *const Self, alias_name: Ident.Idx) ?Ident.Idx {
|
||||
// Search from innermost to outermost scope
|
||||
var i = self.scopes.items.len;
|
||||
while (i > 0) {
|
||||
i -= 1;
|
||||
const scope = &self.scopes.items[i];
|
||||
|
||||
switch (scope.lookupModuleAlias(&self.can_ir.env.idents, alias_name)) {
|
||||
.found => |module_name| return module_name,
|
||||
.not_found => continue,
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Introduce a module alias into scope
|
||||
fn scopeIntroduceModuleAlias(self: *Self, alias_name: Ident.Idx, module_name: Ident.Idx) void {
|
||||
const gpa = self.can_ir.env.gpa;
|
||||
const current_scope = &self.scopes.items[self.scopes.items.len - 1];
|
||||
|
||||
// Simplified introduction without parent lookup for now
|
||||
const result = current_scope.introduceModuleAlias(gpa, &self.can_ir.env.idents, alias_name, module_name, null);
|
||||
|
||||
switch (result) {
|
||||
.success => {},
|
||||
.shadowing_warning => |shadowed_module| {
|
||||
// Create diagnostic for module alias shadowing
|
||||
self.can_ir.pushDiagnostic(CIR.Diagnostic{
|
||||
.shadowing_warning = .{
|
||||
.ident = alias_name,
|
||||
.region = Region.zero(), // TODO: get proper region
|
||||
.original_region = Region.zero(), // TODO: get proper region
|
||||
},
|
||||
});
|
||||
_ = shadowed_module; // Suppress unused variable warning
|
||||
},
|
||||
.already_in_scope => |existing_module| {
|
||||
// Module alias already exists in current scope
|
||||
// For now, just issue a diagnostic
|
||||
self.can_ir.pushDiagnostic(CIR.Diagnostic{
|
||||
.shadowing_warning = .{
|
||||
.ident = alias_name,
|
||||
.region = Region.zero(), // TODO: get proper region
|
||||
.original_region = Region.zero(), // TODO: get proper region
|
||||
},
|
||||
});
|
||||
_ = existing_module; // Suppress unused variable warning
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to look up module aliases in parent scopes only
|
||||
fn scopeLookupModuleInParentScopes(self: *const Self, alias_name: Ident.Idx) ?Ident.Idx {
|
||||
// Search from second-innermost to outermost scope (excluding current scope)
|
||||
if (self.scopes.items.len <= 1) return null;
|
||||
|
||||
var i = self.scopes.items.len - 1;
|
||||
while (i > 0) {
|
||||
i -= 1;
|
||||
const scope = &self.scopes.items[i];
|
||||
|
||||
switch (scope.lookupModuleAlias(&self.can_ir.env.idents, alias_name)) {
|
||||
.found => |module_name| return module_name,
|
||||
.not_found => continue,
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Look up an exposed item across all scopes
|
||||
fn scopeLookupExposedItem(self: *const Self, item_name: Ident.Idx) ?Scope.ExposedItemInfo {
|
||||
// Search from innermost to outermost scope
|
||||
var i = self.scopes.items.len;
|
||||
while (i > 0) {
|
||||
i -= 1;
|
||||
const scope = &self.scopes.items[i];
|
||||
|
||||
switch (scope.lookupExposedItem(&self.can_ir.env.idents, item_name)) {
|
||||
.found => |item_info| return item_info,
|
||||
.not_found => continue,
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Introduce an exposed item into the current scope
|
||||
fn scopeIntroduceExposedItem(self: *Self, item_name: Ident.Idx, item_info: Scope.ExposedItemInfo) void {
|
||||
const gpa = self.can_ir.env.gpa;
|
||||
const current_scope = &self.scopes.items[self.scopes.items.len - 1];
|
||||
|
||||
// Simplified introduction without parent lookup for now
|
||||
const result = current_scope.introduceExposedItem(gpa, &self.can_ir.env.idents, item_name, item_info, null);
|
||||
|
||||
switch (result) {
|
||||
.success => {},
|
||||
.shadowing_warning => |shadowed_info| {
|
||||
// Create diagnostic for exposed item shadowing
|
||||
const item_text = self.can_ir.env.idents.getText(item_name);
|
||||
const shadowed_module_text = self.can_ir.env.idents.getText(shadowed_info.module_name);
|
||||
const current_module_text = self.can_ir.env.idents.getText(item_info.module_name);
|
||||
|
||||
// For now, just add a simple diagnostic message
|
||||
const message = std.fmt.allocPrint(gpa, "Exposed item '{s}' from module '{s}' shadows item from module '{s}'", .{ item_text, current_module_text, shadowed_module_text }) catch |err| collections.utils.exitOnOom(err);
|
||||
const message_str = self.can_ir.env.strings.insert(gpa, message);
|
||||
gpa.free(message);
|
||||
|
||||
self.can_ir.pushDiagnostic(CIR.Diagnostic{
|
||||
.not_implemented = .{
|
||||
.feature = message_str,
|
||||
.region = Region.zero(), // TODO: Get proper region from import statement
|
||||
},
|
||||
});
|
||||
},
|
||||
.already_in_scope => |existing_info| {
|
||||
// Create diagnostic for duplicate exposed item
|
||||
const item_text = self.can_ir.env.idents.getText(item_name);
|
||||
const existing_module_text = self.can_ir.env.idents.getText(existing_info.module_name);
|
||||
const new_module_text = self.can_ir.env.idents.getText(item_info.module_name);
|
||||
|
||||
const message = std.fmt.allocPrint(gpa, "Exposed item '{s}' already imported from module '{s}', cannot import again from module '{s}'", .{ item_text, existing_module_text, new_module_text }) catch |err| collections.utils.exitOnOom(err);
|
||||
const message_str = self.can_ir.env.strings.insert(gpa, message);
|
||||
gpa.free(message);
|
||||
|
||||
self.can_ir.pushDiagnostic(CIR.Diagnostic{
|
||||
.not_implemented = .{
|
||||
.feature = message_str,
|
||||
.region = Region.zero(), // TODO: Get proper region from import statement
|
||||
},
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Look up an exposed item in parent scopes (for shadowing detection)
|
||||
fn scopeLookupExposedItemInParentScopes(self: *const Self, item_name: Ident.Idx) ?Scope.ExposedItemInfo {
|
||||
// Search from second-innermost to outermost scope (excluding current scope)
|
||||
if (self.scopes.items.len <= 1) return null;
|
||||
|
||||
var i = self.scopes.items.len - 1;
|
||||
while (i > 0) {
|
||||
i -= 1;
|
||||
const scope = &self.scopes.items[i];
|
||||
|
||||
switch (scope.lookupExposedItem(&self.can_ir.env.idents, item_name)) {
|
||||
.found => |item_info| return item_info,
|
||||
.not_found => continue,
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Extract the module name from a full qualified name (e.g., "Json" from "json.Json")
|
||||
fn extractModuleName(self: *Self, module_name_ident: Ident.Idx) Ident.Idx {
|
||||
const module_text = self.can_ir.env.idents.getText(module_name_ident);
|
||||
|
||||
// Find the last dot and extract the part after it
|
||||
if (std.mem.lastIndexOf(u8, module_text, ".")) |last_dot_idx| {
|
||||
const extracted_name = module_text[last_dot_idx + 1 ..];
|
||||
return self.can_ir.env.idents.insert(self.can_ir.env.gpa, base.Ident.for_text(extracted_name), Region.zero());
|
||||
} else {
|
||||
// No dot found, return the original name
|
||||
return module_name_ident;
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a parsed TypeAnno into a canonical TypeVar with appropriate Content
|
||||
fn canonicalizeTypeAnnoToTypeVar(self: *Self, type_anno_idx: CIR.TypeAnno.Idx, parent_node_idx: Node.Idx, region: Region) TypeVar {
|
||||
const type_anno = self.can_ir.store.getTypeAnno(type_anno_idx);
|
||||
|
@ -2821,6 +3191,168 @@ fn createAnnotationFromTypeAnno(self: *Self, type_anno_idx: CIR.TypeAnno.Idx, _:
|
|||
return annotation_idx;
|
||||
}
|
||||
|
||||
/// Try to handle field access as a module-qualified lookup.
|
||||
///
|
||||
/// Examples:
|
||||
/// - `Json.utf8` where `Json` is a module alias and `utf8` is an exposed function
|
||||
/// - `Http.get` where `Http` is imported and `get` is available in that module
|
||||
///
|
||||
/// Returns `null` if this is not a module-qualified lookup (e.g., regular field access like `user.name`)
|
||||
fn tryModuleQualifiedLookup(self: *Self, field_access: AST.BinOp) ?CIR.Expr.Idx {
|
||||
const left_expr = self.parse_ir.store.getExpr(field_access.left);
|
||||
if (left_expr != .ident) return null;
|
||||
|
||||
const left_ident = left_expr.ident;
|
||||
const module_alias = self.parse_ir.tokens.resolveIdentifier(left_ident.token) orelse return null;
|
||||
|
||||
// Check if this is a module alias
|
||||
const module_name = self.scopeLookupModule(module_alias) orelse return null;
|
||||
|
||||
// This is a module-qualified lookup
|
||||
const right_expr = self.parse_ir.store.getExpr(field_access.right);
|
||||
if (right_expr != .ident) return null;
|
||||
|
||||
const right_ident = right_expr.ident;
|
||||
const field_name = self.parse_ir.tokens.resolveIdentifier(right_ident.token) orelse return null;
|
||||
|
||||
// Create qualified name by slicing from original source text
|
||||
// The field_access region covers the entire "Module.field" span
|
||||
const region = self.parse_ir.tokenizedRegionToRegion(field_access.region);
|
||||
const source_text = self.parse_ir.source[region.start.offset..region.end.offset];
|
||||
|
||||
const qualified_name = self.can_ir.env.idents.insert(self.can_ir.env.gpa, base.Ident.for_text(source_text), region);
|
||||
|
||||
// Create external declaration
|
||||
const external_decl = CIR.ExternalDecl{
|
||||
.qualified_name = qualified_name,
|
||||
.module_name = module_name,
|
||||
.local_name = field_name,
|
||||
.type_var = self.can_ir.pushFreshTypeVar(@enumFromInt(0), region),
|
||||
.kind = .value,
|
||||
.region = region,
|
||||
};
|
||||
|
||||
const external_idx = self.can_ir.pushExternalDecl(external_decl);
|
||||
|
||||
// Create lookup expression for external declaration
|
||||
const expr_idx = self.can_ir.store.addExpr(CIR.Expr{ .lookup = .{ .external = external_idx } });
|
||||
_ = self.can_ir.setTypeVarAtExpr(expr_idx, Content{ .flex_var = null });
|
||||
return expr_idx;
|
||||
}
|
||||
|
||||
/// Canonicalize regular field access (not module-qualified).
|
||||
///
|
||||
/// Examples:
|
||||
/// - `user.name` - accessing a field on a record
|
||||
/// - `list.map(transform)` - calling a method with arguments
|
||||
/// - `result.isOk` - accessing a field that might be a function
|
||||
fn canonicalizeRegularFieldAccess(self: *Self, field_access: AST.BinOp) ?CIR.Expr.Idx {
|
||||
// Canonicalize the receiver (left side of the dot)
|
||||
const receiver_idx = self.canonicalizeFieldAccessReceiver(field_access) orelse return null;
|
||||
|
||||
// Parse the right side - this could be just a field name or a method call
|
||||
const field_name, const args = self.parseFieldAccessRight(field_access);
|
||||
|
||||
const dot_access_expr = CIR.Expr{
|
||||
.dot_access = .{
|
||||
.receiver = receiver_idx,
|
||||
.field_name = field_name,
|
||||
.args = args,
|
||||
.region = self.parse_ir.tokenizedRegionToRegion(field_access.region),
|
||||
},
|
||||
};
|
||||
|
||||
const expr_idx = self.can_ir.store.addExpr(dot_access_expr);
|
||||
_ = self.can_ir.setTypeVarAtExpr(expr_idx, Content{ .flex_var = null });
|
||||
return expr_idx;
|
||||
}
|
||||
|
||||
/// Canonicalize the receiver (left side) of field access.
|
||||
///
|
||||
/// Examples:
|
||||
/// - In `user.name`, canonicalizes `user`
|
||||
/// - In `getUser().email`, canonicalizes `getUser()`
|
||||
/// - In `[1,2,3].map(fn)`, canonicalizes `[1,2,3]`
|
||||
fn canonicalizeFieldAccessReceiver(self: *Self, field_access: AST.BinOp) ?CIR.Expr.Idx {
|
||||
if (self.canonicalize_expr(field_access.left)) |idx| {
|
||||
return idx;
|
||||
} else {
|
||||
// Failed to canonicalize receiver, return malformed
|
||||
const region = self.parse_ir.tokenizedRegionToRegion(field_access.region);
|
||||
return self.can_ir.pushMalformed(CIR.Expr.Idx, CIR.Diagnostic{ .expr_not_canonicalized = .{
|
||||
.region = region,
|
||||
} });
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse the right side of field access, handling both plain fields and method calls.
|
||||
///
|
||||
/// Examples:
|
||||
/// - `user.name` - returns `("name", null)` for plain field access
|
||||
/// - `list.map(fn)` - returns `("map", args)` where args contains the canonicalized function
|
||||
/// - `obj.method(a, b)` - returns `("method", args)` where args contains canonicalized a and b
|
||||
fn parseFieldAccessRight(self: *Self, field_access: AST.BinOp) struct { Ident.Idx, ?CIR.Expr.Span } {
|
||||
const right_expr = self.parse_ir.store.getExpr(field_access.right);
|
||||
|
||||
return switch (right_expr) {
|
||||
.apply => |apply| self.parseMethodCall(apply),
|
||||
.ident => |ident| .{ self.resolveIdentOrFallback(ident.token), null },
|
||||
else => .{ self.createUnknownIdent(), null },
|
||||
};
|
||||
}
|
||||
|
||||
/// Parse a method call on the right side of field access.
|
||||
///
|
||||
/// Examples:
|
||||
/// - `.map(transform)` - extracts "map" as method name and canonicalizes `transform` argument
|
||||
/// - `.filter(predicate)` - extracts "filter" and canonicalizes `predicate`
|
||||
/// - `.fold(0, combine)` - extracts "fold" and canonicalizes both `0` and `combine` arguments
|
||||
fn parseMethodCall(self: *Self, apply: @TypeOf(@as(AST.Expr, undefined).apply)) struct { Ident.Idx, ?CIR.Expr.Span } {
|
||||
const method_expr = self.parse_ir.store.getExpr(apply.@"fn");
|
||||
const field_name = switch (method_expr) {
|
||||
.ident => |ident| self.resolveIdentOrFallback(ident.token),
|
||||
else => self.createUnknownIdent(),
|
||||
};
|
||||
|
||||
// Canonicalize the arguments using scratch system
|
||||
const scratch_top = self.can_ir.store.scratchExprTop();
|
||||
for (self.parse_ir.store.exprSlice(apply.args)) |arg_idx| {
|
||||
if (self.canonicalize_expr(arg_idx)) |canonicalized| {
|
||||
self.can_ir.store.addScratchExpr(canonicalized);
|
||||
} else {
|
||||
self.can_ir.store.clearScratchExprsFrom(scratch_top);
|
||||
return .{ field_name, null };
|
||||
}
|
||||
}
|
||||
const args = self.can_ir.store.exprSpanFrom(scratch_top);
|
||||
|
||||
return .{ field_name, args };
|
||||
}
|
||||
|
||||
/// Resolve an identifier token or return a fallback "unknown" identifier.
|
||||
///
|
||||
/// This helps maintain the "inform don't block" philosophy - even if we can't
|
||||
/// resolve an identifier (due to malformed input), we continue compilation.
|
||||
///
|
||||
/// Examples:
|
||||
/// - Valid token for "name" -> returns the interned identifier for "name"
|
||||
/// - Malformed/missing token -> returns identifier for "unknown"
|
||||
fn resolveIdentOrFallback(self: *Self, token: Token.Idx) Ident.Idx {
|
||||
if (self.parse_ir.tokens.resolveIdentifier(token)) |ident_idx| {
|
||||
return ident_idx;
|
||||
} else {
|
||||
return self.createUnknownIdent();
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an "unknown" identifier for fallback cases.
|
||||
///
|
||||
/// Used when we encounter malformed or unexpected syntax but want to continue
|
||||
/// compilation instead of stopping. This supports the compiler's "inform don't block" approach.
|
||||
fn createUnknownIdent(self: *Self) Ident.Idx {
|
||||
return self.can_ir.env.idents.insert(self.can_ir.env.gpa, base.Ident.for_text("unknown"), Region.zero());
|
||||
}
|
||||
|
||||
/// Context helper for Scope tests
|
||||
const ScopeTestContext = struct {
|
||||
self: Self,
|
||||
|
|
|
@ -45,6 +45,8 @@ temp_source_for_sexpr: ?[]const u8 = null,
|
|||
all_defs: Def.Span,
|
||||
/// All the top-level statements in the module, populated by calling `canonicalize_file`
|
||||
all_statements: Statement.Span,
|
||||
/// All external declarations referenced in this module
|
||||
external_decls: std.ArrayList(ExternalDecl),
|
||||
|
||||
/// Initialize the IR for a module's canonicalization info.
|
||||
///
|
||||
|
@ -66,12 +68,14 @@ pub fn init(env: *ModuleEnv) CIR {
|
|||
.store = NodeStore.initCapacity(env.gpa, NODE_STORE_CAPACITY),
|
||||
.all_defs = .{ .span = .{ .start = 0, .len = 0 } },
|
||||
.all_statements = .{ .span = .{ .start = 0, .len = 0 } },
|
||||
.external_decls = std.ArrayList(ExternalDecl).init(env.gpa),
|
||||
};
|
||||
}
|
||||
|
||||
/// Deinit the IR's memory.
|
||||
pub fn deinit(self: *CIR) void {
|
||||
self.store.deinit();
|
||||
self.external_decls.deinit();
|
||||
}
|
||||
|
||||
/// Records a diagnostic error during canonicalization without blocking compilation.
|
||||
|
@ -346,6 +350,32 @@ pub fn setTypeVarAt(self: *CIR, at_idx: Node.Idx, content: types.Content) types.
|
|||
return var_;
|
||||
}
|
||||
|
||||
/// Adds an external declaration to the CIR and returns its index
|
||||
pub fn pushExternalDecl(self: *CIR, decl: ExternalDecl) ExternalDecl.Idx {
|
||||
const idx = @as(u32, @intCast(self.external_decls.items.len));
|
||||
self.external_decls.append(decl) catch |err| exitOnOom(err);
|
||||
return @enumFromInt(idx);
|
||||
}
|
||||
|
||||
/// Retrieves an external declaration by its index
|
||||
pub fn getExternalDecl(self: *const CIR, idx: ExternalDecl.Idx) *const ExternalDecl {
|
||||
return &self.external_decls.items[@intFromEnum(idx)];
|
||||
}
|
||||
|
||||
/// Adds multiple external declarations and returns a span
|
||||
pub fn pushExternalDecls(self: *CIR, decls: []const ExternalDecl) ExternalDecl.Span {
|
||||
const start = @as(u32, @intCast(self.external_decls.items.len));
|
||||
for (decls) |decl| {
|
||||
self.external_decls.append(decl) catch |err| exitOnOom(err);
|
||||
}
|
||||
return .{ .span = .{ .start = start, .len = @as(u32, @intCast(decls.len)) } };
|
||||
}
|
||||
|
||||
/// Gets a slice of external declarations from a span
|
||||
pub fn sliceExternalDecls(self: *const CIR, span: ExternalDecl.Span) []const ExternalDecl {
|
||||
return self.external_decls.items[span.span.start .. span.span.start + span.span.len];
|
||||
}
|
||||
|
||||
// Helper to add type index info to a s-expr node
|
||||
fn appendTypeVar(node: *sexpr.Expr, gpa: std.mem.Allocator, name: []const u8, type_idx: TypeVar) void {
|
||||
var type_node = sexpr.Expr.init(gpa, name);
|
||||
|
@ -591,9 +621,10 @@ pub const Statement = union(enum) {
|
|||
|
||||
var exposes_node = sexpr.Expr.init(gpa, "exposes");
|
||||
const exposes_slice = ir.store.sliceExposedItems(s.exposes);
|
||||
for (exposes_slice) |_| {
|
||||
// TODO: Implement ExposedItem.toSExpr when ExposedItem structure is complete
|
||||
exposes_node.appendString(gpa, "exposed_item");
|
||||
for (exposes_slice) |exposed_idx| {
|
||||
const exposed_item = ir.store.getExposedItem(exposed_idx);
|
||||
const exposed_sexpr = exposed_item.toSExpr(gpa, ir.env);
|
||||
exposes_node.appendNode(gpa, &exposed_sexpr);
|
||||
}
|
||||
node.appendNode(gpa, &exposes_node);
|
||||
|
||||
|
@ -1024,6 +1055,27 @@ pub const ExposedItem = struct {
|
|||
|
||||
pub const Idx = enum(u32) { _ };
|
||||
pub const Span = struct { span: DataSpan };
|
||||
|
||||
pub fn toSExpr(self: ExposedItem, gpa: std.mem.Allocator, env: *const ModuleEnv) sexpr.Expr {
|
||||
var node = sexpr.Expr.init(gpa, "exposed_item");
|
||||
|
||||
// Add the original name
|
||||
const name_text = env.idents.getText(self.name);
|
||||
node.appendString(gpa, name_text);
|
||||
|
||||
// Add the alias if present
|
||||
if (self.alias) |alias_idx| {
|
||||
const alias_text = env.idents.getText(alias_idx);
|
||||
node.appendString(gpa, alias_text);
|
||||
}
|
||||
|
||||
// Add wildcard indicator if needed
|
||||
if (self.is_wildcard) {
|
||||
node.appendString(gpa, "wildcard");
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
/// An expression that has been canonicalized.
|
||||
|
@ -1071,7 +1123,10 @@ pub const Expr = union(enum) {
|
|||
bound: types.Num.Int.Precision,
|
||||
region: Region,
|
||||
},
|
||||
lookup: Lookup,
|
||||
lookup: union(enum) {
|
||||
local: Lookup,
|
||||
external: ExternalDecl.Idx,
|
||||
},
|
||||
// TODO introduce a new node for re-assign here, used by Var instead of lookup
|
||||
list: struct {
|
||||
elem_var: TypeVar,
|
||||
|
@ -1212,7 +1267,14 @@ pub const Expr = union(enum) {
|
|||
.str_segment => |e| return e.region,
|
||||
.str => |e| return e.region,
|
||||
.single_quote => |e| return e.region,
|
||||
.lookup => |e| return e.region,
|
||||
.lookup => |e| switch (e) {
|
||||
.local => |local| return local.region,
|
||||
.external => |_| {
|
||||
// External lookups don't have a direct region access from Expr context
|
||||
// The region should be handled where the CIR context is available
|
||||
return null;
|
||||
},
|
||||
},
|
||||
.list => |e| return e.region,
|
||||
.tuple => |e| return e.region,
|
||||
.when => |e| return e.region,
|
||||
|
@ -1419,13 +1481,26 @@ pub const Expr = union(enum) {
|
|||
return tuple_node;
|
||||
},
|
||||
.lookup => |l| {
|
||||
var lookup_node = sexpr.Expr.init(gpa, "e_lookup");
|
||||
lookup_node.appendRegionInfo(gpa, ir.calcRegionInfo(l.region));
|
||||
switch (l) {
|
||||
.local => |local| {
|
||||
var lookup_node = sexpr.Expr.init(gpa, "e_lookup_local");
|
||||
lookup_node.appendRegionInfo(gpa, ir.calcRegionInfo(local.region));
|
||||
|
||||
var pattern_idx = formatPatternIdxNode(gpa, l.pattern_idx);
|
||||
lookup_node.appendNode(gpa, &pattern_idx);
|
||||
var pattern_idx = formatPatternIdxNode(gpa, local.pattern_idx);
|
||||
lookup_node.appendNode(gpa, &pattern_idx);
|
||||
|
||||
return lookup_node;
|
||||
return lookup_node;
|
||||
},
|
||||
.external => |external_idx| {
|
||||
var lookup_node = sexpr.Expr.init(gpa, "e_lookup_external");
|
||||
|
||||
const external_decl = ir.getExternalDecl(external_idx);
|
||||
var external_sexpr = external_decl.toSExpr(ir, env);
|
||||
lookup_node.appendNode(gpa, &external_sexpr);
|
||||
|
||||
return lookup_node;
|
||||
},
|
||||
}
|
||||
},
|
||||
.when => |e| {
|
||||
var when_branch_node = sexpr.Expr.init(gpa, "e_when");
|
||||
|
@ -1858,6 +1933,73 @@ pub const Annotation = struct {
|
|||
}
|
||||
};
|
||||
|
||||
/// External declaration node for cross-module references
|
||||
///
|
||||
/// This node represents a reference to a declaration from another module
|
||||
/// that hasn't been resolved yet. It serves as a placeholder during
|
||||
/// canonicalization that will be populated with type information
|
||||
/// later during dependency resolution.
|
||||
pub const ExternalDecl = struct {
|
||||
/// Fully qualified name (e.g., "json.Json.utf8")
|
||||
qualified_name: Ident.Idx,
|
||||
|
||||
/// Module this decl comes from (e.g., "json.Json")
|
||||
module_name: Ident.Idx,
|
||||
|
||||
/// Local name within that module (e.g., "utf8")
|
||||
local_name: Ident.Idx,
|
||||
|
||||
/// Type information (populated later after dependency resolution)
|
||||
type_var: TypeVar,
|
||||
|
||||
/// Whether this is a value or type declaration
|
||||
kind: enum { value, type },
|
||||
|
||||
/// Region where this was referenced
|
||||
region: Region,
|
||||
|
||||
pub const Idx = enum(u32) { _ };
|
||||
pub const Span = struct { span: DataSpan };
|
||||
|
||||
pub fn toSExpr(self: *const @This(), ir: *const CIR, env: *ModuleEnv) sexpr.Expr {
|
||||
const gpa = ir.env.gpa;
|
||||
var node = sexpr.Expr.init(gpa, "external_decl");
|
||||
node.appendRegionInfo(gpa, ir.calcRegionInfo(self.region));
|
||||
|
||||
// Add qualified name
|
||||
var qualified_name_node = sexpr.Expr.init(gpa, "qualified_name");
|
||||
const qualified_name_str = env.idents.getText(self.qualified_name);
|
||||
qualified_name_node.appendString(gpa, qualified_name_str);
|
||||
node.appendNode(gpa, &qualified_name_node);
|
||||
|
||||
// Add module name
|
||||
var module_name_node = sexpr.Expr.init(gpa, "module_name");
|
||||
const module_name_str = env.idents.getText(self.module_name);
|
||||
module_name_node.appendString(gpa, module_name_str);
|
||||
node.appendNode(gpa, &module_name_node);
|
||||
|
||||
// Add local name
|
||||
var local_name_node = sexpr.Expr.init(gpa, "local_name");
|
||||
const local_name_str = env.idents.getText(self.local_name);
|
||||
local_name_node.appendString(gpa, local_name_str);
|
||||
node.appendNode(gpa, &local_name_node);
|
||||
|
||||
// Add kind
|
||||
var kind_node = sexpr.Expr.init(gpa, "kind");
|
||||
const kind_str = switch (self.kind) {
|
||||
.value => "value",
|
||||
.type => "type",
|
||||
};
|
||||
kind_node.appendString(gpa, kind_str);
|
||||
node.appendNode(gpa, &kind_node);
|
||||
|
||||
// Add type variable info
|
||||
appendTypeVar(&node, gpa, "type_var", self.type_var);
|
||||
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
/// Tracks type variables introduced during annotation canonicalization
|
||||
pub const IntroducedVariables = struct {
|
||||
/// Named type variables (e.g., 'a' in 'a -> a')
|
||||
|
|
|
@ -44,6 +44,7 @@ pub const Tag = enum {
|
|||
expr_record,
|
||||
expr_field_access,
|
||||
expr_static_dispatch,
|
||||
expr_external_lookup,
|
||||
expr_dot_access,
|
||||
expr_apply,
|
||||
expr_string,
|
||||
|
@ -94,6 +95,8 @@ pub const Tag = enum {
|
|||
pattern_underscore,
|
||||
// Definitions
|
||||
def,
|
||||
// Exposed Items
|
||||
exposed_item,
|
||||
|
||||
// todo -- put me somewhere and rename maybe
|
||||
if_branch,
|
||||
|
|
|
@ -168,10 +168,14 @@ pub fn getExpr(store: *const NodeStore, expr: CIR.Expr.Idx) CIR.Expr {
|
|||
|
||||
switch (node.tag) {
|
||||
.expr_var => {
|
||||
return CIR.Expr{ .lookup = .{
|
||||
return CIR.Expr{ .lookup = .{ .local = .{
|
||||
.pattern_idx = @enumFromInt(node.data_1),
|
||||
.region = node.region,
|
||||
} };
|
||||
} } };
|
||||
},
|
||||
.expr_external_lookup => {
|
||||
// Handle external lookups
|
||||
return CIR.Expr{ .lookup = .{ .external = @enumFromInt(node.data_1) } };
|
||||
},
|
||||
.expr_int => {
|
||||
// Retrieve the literal index from data_1
|
||||
|
@ -580,9 +584,19 @@ pub fn getAnnotation(store: *NodeStore, annotation: CIR.Annotation.Idx) CIR.Anno
|
|||
|
||||
/// Retrieves an exposed item from the store.
|
||||
pub fn getExposedItem(store: *NodeStore, exposedItem: CIR.ExposedItem.Idx) CIR.ExposedItem {
|
||||
_ = store;
|
||||
_ = exposedItem;
|
||||
@panic("TODO: implement getExposedItem");
|
||||
const node_idx: Node.Idx = @enumFromInt(@intFromEnum(exposedItem));
|
||||
const node = store.nodes.get(node_idx);
|
||||
|
||||
switch (node.tag) {
|
||||
.exposed_item => {
|
||||
return CIR.ExposedItem{
|
||||
.name = @bitCast(node.data_1),
|
||||
.alias = if (node.data_2 == 0) null else @bitCast(node.data_2),
|
||||
.is_wildcard = node.data_3 != 0,
|
||||
};
|
||||
},
|
||||
else => std.debug.panic("Expected exposed_item node, got {s}\n", .{@tagName(node.tag)}),
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a statement node to the store.
|
||||
|
@ -689,9 +703,20 @@ pub fn addExpr(store: *NodeStore, expr: CIR.Expr) CIR.Expr.Idx {
|
|||
|
||||
switch (expr) {
|
||||
.lookup => |e| {
|
||||
node.region = e.region;
|
||||
node.tag = .expr_var;
|
||||
node.data_1 = @intFromEnum(e.pattern_idx);
|
||||
switch (e) {
|
||||
.local => |local| {
|
||||
node.region = local.region;
|
||||
node.tag = .expr_var;
|
||||
node.data_1 = @intFromEnum(local.pattern_idx);
|
||||
},
|
||||
.external => |external_idx| {
|
||||
// For external lookups, store the external decl index
|
||||
// Use external lookup tag to distinguish from local lookups
|
||||
node.region = base.Region.zero();
|
||||
node.tag = .expr_external_lookup;
|
||||
node.data_1 = @intFromEnum(external_idx);
|
||||
},
|
||||
}
|
||||
},
|
||||
.int => |e| {
|
||||
node.region = e.region;
|
||||
|
@ -1089,16 +1114,16 @@ pub fn addAnnotation(store: *NodeStore, annotation: CIR.Annotation) CIR.Annotati
|
|||
|
||||
/// Adds an exposed item to the store.
|
||||
pub fn addExposedItem(store: *NodeStore, exposedItem: CIR.ExposedItem) CIR.ExposedItem.Idx {
|
||||
const node = Node{};
|
||||
|
||||
switch (exposedItem) {
|
||||
else => {
|
||||
std.debug.panic("Exposed Item of type {s} not yet implemented in Can\n", .{@tagName(exposedItem)});
|
||||
},
|
||||
}
|
||||
const node = Node{
|
||||
.data_1 = @bitCast(exposedItem.name),
|
||||
.data_2 = if (exposedItem.alias) |alias| @bitCast(alias) else 0,
|
||||
.data_3 = if (exposedItem.is_wildcard) 1 else 0,
|
||||
.region = base.Region.zero(),
|
||||
.tag = .exposed_item,
|
||||
};
|
||||
|
||||
const nid = store.nodes.append(store.gpa, node);
|
||||
return @enumFromInt(nid);
|
||||
return @enumFromInt(@intFromEnum(nid));
|
||||
}
|
||||
|
||||
/// Adds a definition to the store.
|
||||
|
@ -1294,6 +1319,34 @@ pub fn annoRecordFieldSpanFrom(store: *NodeStore, start: u32) CIR.AnnoRecordFiel
|
|||
return .{ .span = .{ .start = ed_start, .len = @as(u32, @intCast(end)) - start } };
|
||||
}
|
||||
|
||||
/// Returns the current top of the scratch exposed items buffer.
|
||||
pub fn scratchExposedItemTop(store: *NodeStore) u32 {
|
||||
return store.scratch_exposed_items.top();
|
||||
}
|
||||
|
||||
/// Adds an exposed item to the scratch buffer.
|
||||
pub fn addScratchExposedItem(store: *NodeStore, idx: CIR.ExposedItem.Idx) void {
|
||||
store.scratch_exposed_items.append(store.gpa, idx);
|
||||
}
|
||||
|
||||
/// Creates a span from the scratch exposed items starting at the given index.
|
||||
pub fn exposedItemSpanFrom(store: *NodeStore, start: u32) CIR.ExposedItem.Span {
|
||||
const end = store.scratch_exposed_items.top();
|
||||
defer store.scratch_exposed_items.clearFrom(start);
|
||||
var i = @as(usize, @intCast(start));
|
||||
const ed_start = @as(u32, @intCast(store.extra_data.items.len));
|
||||
while (i < end) {
|
||||
store.extra_data.append(store.gpa, @intFromEnum(store.scratch_exposed_items.items.items[i])) catch |err| exitOnOom(err);
|
||||
i += 1;
|
||||
}
|
||||
return .{ .span = .{ .start = ed_start, .len = @as(u32, @intCast(end)) - start } };
|
||||
}
|
||||
|
||||
/// Clears scratch exposed items from the given index.
|
||||
pub fn clearScratchExposedItemsFrom(store: *NodeStore, start: u32) void {
|
||||
store.scratch_exposed_items.clearFrom(start);
|
||||
}
|
||||
|
||||
/// Returns the start position for a new Span of annoRecordFieldIdxs in scratch
|
||||
pub fn scratchAnnoRecordFieldTop(store: *NodeStore) u32 {
|
||||
return store.scratch_anno_record_fields.top();
|
||||
|
|
|
@ -16,6 +16,10 @@ aliases: std.AutoHashMapUnmanaged(Ident.Idx, CIR.Pattern.Idx),
|
|||
type_decls: std.AutoHashMapUnmanaged(Ident.Idx, CIR.Statement.Idx),
|
||||
/// Maps type variables to their type annotation indices
|
||||
type_vars: std.AutoHashMapUnmanaged(Ident.Idx, CIR.TypeAnno.Idx),
|
||||
/// Maps module alias names to their full module names
|
||||
module_aliases: std.AutoHashMapUnmanaged(Ident.Idx, Ident.Idx),
|
||||
/// Maps exposed item names to their source modules and original names (for import resolution)
|
||||
exposed_items: std.AutoHashMapUnmanaged(Ident.Idx, ExposedItemInfo),
|
||||
is_function_boundary: bool,
|
||||
|
||||
/// Initialize the scope
|
||||
|
@ -25,6 +29,8 @@ pub fn init(is_function_boundary: bool) Scope {
|
|||
.aliases = std.AutoHashMapUnmanaged(Ident.Idx, CIR.Pattern.Idx){},
|
||||
.type_decls = std.AutoHashMapUnmanaged(Ident.Idx, CIR.Statement.Idx){},
|
||||
.type_vars = std.AutoHashMapUnmanaged(Ident.Idx, CIR.TypeAnno.Idx){},
|
||||
.module_aliases = std.AutoHashMapUnmanaged(Ident.Idx, Ident.Idx){},
|
||||
.exposed_items = std.AutoHashMapUnmanaged(Ident.Idx, ExposedItemInfo){},
|
||||
.is_function_boundary = is_function_boundary,
|
||||
};
|
||||
}
|
||||
|
@ -35,6 +41,8 @@ pub fn deinit(self: *Scope, gpa: std.mem.Allocator) void {
|
|||
self.aliases.deinit(gpa);
|
||||
self.type_decls.deinit(gpa);
|
||||
self.type_vars.deinit(gpa);
|
||||
self.module_aliases.deinit(gpa);
|
||||
self.exposed_items.deinit(gpa);
|
||||
}
|
||||
|
||||
/// Scope management types and structures
|
||||
|
@ -64,6 +72,24 @@ pub const TypeVarLookupResult = union(enum) {
|
|||
not_found: void,
|
||||
};
|
||||
|
||||
/// Result of looking up a module alias
|
||||
pub const ModuleAliasLookupResult = union(enum) {
|
||||
found: Ident.Idx,
|
||||
not_found: void,
|
||||
};
|
||||
|
||||
/// Information about an exposed item
|
||||
pub const ExposedItemInfo = struct {
|
||||
module_name: Ident.Idx,
|
||||
original_name: Ident.Idx,
|
||||
};
|
||||
|
||||
/// Result of looking up an exposed item
|
||||
pub const ExposedItemLookupResult = union(enum) {
|
||||
found: ExposedItemInfo,
|
||||
not_found: void,
|
||||
};
|
||||
|
||||
/// Result of introducing an identifier
|
||||
pub const IntroduceResult = union(enum) {
|
||||
success: void,
|
||||
|
@ -93,20 +119,38 @@ pub const TypeVarIntroduceResult = union(enum) {
|
|||
already_in_scope: CIR.TypeAnno.Idx, // The type variable already exists in this scope
|
||||
};
|
||||
|
||||
/// Result of introducing a module alias
|
||||
pub const ModuleAliasIntroduceResult = union(enum) {
|
||||
success: void,
|
||||
shadowing_warning: Ident.Idx, // The module alias that was shadowed
|
||||
already_in_scope: Ident.Idx, // The module alias already exists in this scope
|
||||
};
|
||||
|
||||
/// Result of introducing an exposed item
|
||||
pub const ExposedItemIntroduceResult = union(enum) {
|
||||
success: void,
|
||||
shadowing_warning: ExposedItemInfo, // The exposed item that was shadowed
|
||||
already_in_scope: ExposedItemInfo, // The exposed item already exists in this scope
|
||||
};
|
||||
|
||||
/// Item kinds in a scope
|
||||
pub const ItemKind = enum { ident, alias, type_decl, type_var };
|
||||
pub const ItemKind = enum { ident, alias, type_decl, type_var, module_alias, exposed_item };
|
||||
|
||||
/// Get the appropriate map for the given item kind
|
||||
pub fn items(scope: *Scope, comptime item_kind: ItemKind) switch (item_kind) {
|
||||
.ident, .alias => *std.AutoHashMapUnmanaged(Ident.Idx, CIR.Pattern.Idx),
|
||||
.type_decl => *std.AutoHashMapUnmanaged(Ident.Idx, CIR.Statement.Idx),
|
||||
.type_var => *std.AutoHashMapUnmanaged(Ident.Idx, CIR.TypeAnno.Idx),
|
||||
.module_alias => *std.AutoHashMapUnmanaged(Ident.Idx, Ident.Idx),
|
||||
.exposed_item => *std.AutoHashMapUnmanaged(Ident.Idx, ExposedItemInfo),
|
||||
} {
|
||||
return switch (item_kind) {
|
||||
.ident => &scope.idents,
|
||||
.alias => &scope.aliases,
|
||||
.type_decl => &scope.type_decls,
|
||||
.type_var => &scope.type_vars,
|
||||
.module_alias => &scope.module_aliases,
|
||||
.exposed_item => &scope.exposed_items,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -115,12 +159,16 @@ pub fn itemsConst(scope: *const Scope, comptime item_kind: ItemKind) switch (ite
|
|||
.ident, .alias => *const std.AutoHashMapUnmanaged(Ident.Idx, CIR.Pattern.Idx),
|
||||
.type_decl => *const std.AutoHashMapUnmanaged(Ident.Idx, CIR.Statement.Idx),
|
||||
.type_var => *const std.AutoHashMapUnmanaged(Ident.Idx, CIR.TypeAnno.Idx),
|
||||
.module_alias => *const std.AutoHashMapUnmanaged(Ident.Idx, Ident.Idx),
|
||||
.exposed_item => *const std.AutoHashMapUnmanaged(Ident.Idx, ExposedItemInfo),
|
||||
} {
|
||||
return switch (item_kind) {
|
||||
.ident => &scope.idents,
|
||||
.alias => &scope.aliases,
|
||||
.type_decl => &scope.type_decls,
|
||||
.type_var => &scope.type_vars,
|
||||
.module_alias => &scope.module_aliases,
|
||||
.exposed_item => &scope.exposed_items,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -129,6 +177,8 @@ pub fn put(scope: *Scope, gpa: std.mem.Allocator, comptime item_kind: ItemKind,
|
|||
.ident, .alias => CIR.Pattern.Idx,
|
||||
.type_decl => CIR.Statement.Idx,
|
||||
.type_var => CIR.TypeAnno.Idx,
|
||||
.module_alias => Ident.Idx,
|
||||
.exposed_item => ExposedItemInfo,
|
||||
}) void {
|
||||
scope.items(item_kind).put(gpa, name, value) catch |err| collections.utils.exitOnOom(err);
|
||||
}
|
||||
|
@ -225,3 +275,93 @@ pub fn lookupTypeVar(scope: *const Scope, ident_store: *const base.Ident.Store,
|
|||
}
|
||||
return TypeVarLookupResult{ .not_found = {} };
|
||||
}
|
||||
|
||||
/// Look up a module alias in this scope
|
||||
pub fn lookupModuleAlias(scope: *const Scope, ident_store: *const base.Ident.Store, name: Ident.Idx) ModuleAliasLookupResult {
|
||||
// Search by comparing text content, not identifier index
|
||||
var iter = scope.module_aliases.iterator();
|
||||
while (iter.next()) |entry| {
|
||||
if (ident_store.identsHaveSameText(name, entry.key_ptr.*)) {
|
||||
return ModuleAliasLookupResult{ .found = entry.value_ptr.* };
|
||||
}
|
||||
}
|
||||
return ModuleAliasLookupResult{ .not_found = {} };
|
||||
}
|
||||
|
||||
/// Introduce a module alias into this scope
|
||||
pub fn introduceModuleAlias(
|
||||
scope: *Scope,
|
||||
gpa: std.mem.Allocator,
|
||||
ident_store: *const base.Ident.Store,
|
||||
alias_name: Ident.Idx,
|
||||
module_name: Ident.Idx,
|
||||
parent_lookup_fn: ?fn (Ident.Idx) ?Ident.Idx,
|
||||
) ModuleAliasIntroduceResult {
|
||||
// Check if already exists in current scope by comparing text content
|
||||
var iter = scope.module_aliases.iterator();
|
||||
while (iter.next()) |entry| {
|
||||
if (ident_store.identsHaveSameText(alias_name, entry.key_ptr.*)) {
|
||||
// Module alias already exists in this scope
|
||||
return ModuleAliasIntroduceResult{ .already_in_scope = entry.value_ptr.* };
|
||||
}
|
||||
}
|
||||
|
||||
// Check for shadowing in parent scopes
|
||||
var shadowed_module: ?Ident.Idx = null;
|
||||
if (parent_lookup_fn) |lookup_fn| {
|
||||
shadowed_module = lookup_fn(alias_name);
|
||||
}
|
||||
|
||||
scope.put(gpa, .module_alias, alias_name, module_name);
|
||||
|
||||
if (shadowed_module) |module| {
|
||||
return ModuleAliasIntroduceResult{ .shadowing_warning = module };
|
||||
}
|
||||
|
||||
return ModuleAliasIntroduceResult{ .success = {} };
|
||||
}
|
||||
|
||||
/// Look up an exposed item in this scope
|
||||
pub fn lookupExposedItem(scope: *const Scope, ident_store: *const base.Ident.Store, name: Ident.Idx) ExposedItemLookupResult {
|
||||
// Search by comparing text content, not identifier index
|
||||
var iter = scope.exposed_items.iterator();
|
||||
while (iter.next()) |entry| {
|
||||
if (ident_store.identsHaveSameText(name, entry.key_ptr.*)) {
|
||||
return ExposedItemLookupResult{ .found = entry.value_ptr.* };
|
||||
}
|
||||
}
|
||||
return ExposedItemLookupResult{ .not_found = {} };
|
||||
}
|
||||
|
||||
/// Introduce an exposed item into this scope
|
||||
pub fn introduceExposedItem(
|
||||
scope: *Scope,
|
||||
gpa: std.mem.Allocator,
|
||||
ident_store: *const base.Ident.Store,
|
||||
item_name: Ident.Idx,
|
||||
item_info: ExposedItemInfo,
|
||||
parent_lookup_fn: ?fn (Ident.Idx) ?ExposedItemInfo,
|
||||
) ExposedItemIntroduceResult {
|
||||
// Check if already exists in current scope by comparing text content
|
||||
var iter = scope.exposed_items.iterator();
|
||||
while (iter.next()) |entry| {
|
||||
if (ident_store.identsHaveSameText(item_name, entry.key_ptr.*)) {
|
||||
// Exposed item already exists in this scope
|
||||
return ExposedItemIntroduceResult{ .already_in_scope = entry.value_ptr.* };
|
||||
}
|
||||
}
|
||||
|
||||
// Check for shadowing in parent scopes
|
||||
var shadowed_info: ?ExposedItemInfo = null;
|
||||
if (parent_lookup_fn) |lookup_fn| {
|
||||
shadowed_info = lookup_fn(item_name);
|
||||
}
|
||||
|
||||
scope.put(gpa, .exposed_item, item_name, item_info);
|
||||
|
||||
if (shadowed_info) |info| {
|
||||
return ExposedItemIntroduceResult{ .shadowing_warning = info };
|
||||
}
|
||||
|
||||
return ExposedItemIntroduceResult{ .success = {} };
|
||||
}
|
||||
|
|
|
@ -875,6 +875,7 @@ fn parseStmtByType(self: *Parser, statementType: StatementType) ?AST.Statement.I
|
|||
var exposes = AST.ExposedItem.Span{ .span = base.DataSpan.empty() };
|
||||
const module_name_tok = self.pos;
|
||||
var end = self.pos;
|
||||
// Handle 'as' clause if present
|
||||
if (self.peekNext() == .KwAs) {
|
||||
self.advance(); // Advance past UpperIdent
|
||||
self.advance(); // Advance past KwAs
|
||||
|
@ -885,8 +886,12 @@ fn parseStmtByType(self: *Parser, statementType: StatementType) ?AST.Statement.I
|
|||
self.advance();
|
||||
return malformed;
|
||||
};
|
||||
} else if (self.peekNext() == .KwExposing) {
|
||||
self.advance(); // Advance past ident
|
||||
} else {
|
||||
self.advance(); // Advance past identifier
|
||||
}
|
||||
|
||||
// Handle 'exposing' clause if present (can occur with or without 'as')
|
||||
if (self.peek() == .KwExposing) {
|
||||
self.advance(); // Advance past KwExposing
|
||||
self.expect(.OpenSquare) catch {
|
||||
return self.pushMalformed(AST.Statement.Idx, .import_exposing_no_open, start);
|
||||
|
@ -901,8 +906,6 @@ fn parseStmtByType(self: *Parser, statementType: StatementType) ?AST.Statement.I
|
|||
return self.pushMalformed(AST.Statement.Idx, .import_exposing_no_close, start);
|
||||
};
|
||||
exposes = self.store.exposedItemSpanFrom(scratch_top);
|
||||
} else {
|
||||
self.advance(); // Advance past identifier
|
||||
}
|
||||
const statement_idx = self.store.addStatement(.{ .import = .{
|
||||
.module_name_tok = module_name_tok,
|
||||
|
|
8
src/snapshots/can_basic_scoping.md
generated
8
src/snapshots/can_basic_scoping.md
generated
|
@ -170,18 +170,18 @@ outerFunc = |_| {
|
|||
(ident "z"))
|
||||
(e_binop (12:13-13:10)
|
||||
"add"
|
||||
(e_lookup (12:13-12:14) (pid 84))
|
||||
(e_lookup (12:17-12:18) (pid 77))))
|
||||
(e_lookup_local (12:13-12:14) (pid 84))
|
||||
(e_lookup_local (12:17-12:18) (pid 77))))
|
||||
(e_binop (13:9-14:6)
|
||||
"add"
|
||||
(e_lookup (13:9-13:10) (pid 91))
|
||||
(e_lookup_local (13:9-13:10) (pid 91))
|
||||
(e_int (13:13-13:14)
|
||||
(int_var 98)
|
||||
(precision_var 97)
|
||||
(literal "1")
|
||||
(value "TODO")
|
||||
(bound "u8")))))
|
||||
(e_lookup (15:5-15:16) (pid 90)))))))
|
||||
(e_lookup_local (15:5-15:16) (pid 90)))))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
6
src/snapshots/can_dot_access_with_vars.md
generated
6
src/snapshots/can_dot_access_with_vars.md
generated
|
@ -94,7 +94,7 @@ CloseCurly(5:1-5:2),EndOfFile(5:2-5:2),
|
|||
(ident "x")))
|
||||
(e_binop (3:14-4:9)
|
||||
"add"
|
||||
(e_lookup (3:14-3:15) (pid 86))
|
||||
(e_lookup_local (3:14-3:15) (pid 86))
|
||||
(e_int (3:18-3:19)
|
||||
(int_var 89)
|
||||
(precision_var 88)
|
||||
|
@ -102,9 +102,9 @@ CloseCurly(5:1-5:2),EndOfFile(5:2-5:2),
|
|||
(value "TODO")
|
||||
(bound "u8")))))
|
||||
(e_dot_access (4:5-5:2)
|
||||
(e_lookup (4:5-4:9) (pid 72))
|
||||
(e_lookup_local (4:5-4:9) (pid 72))
|
||||
"map"
|
||||
(e_lookup (4:14-4:16) (pid 85))))
|
||||
(e_lookup_local (4:14-4:16) (pid 85))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
309
src/snapshots/can_import_comprehensive.md
generated
Normal file
309
src/snapshots/can_import_comprehensive.md
generated
Normal file
|
@ -0,0 +1,309 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Comprehensive import test with various module access patterns
|
||||
type=file
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
module []
|
||||
|
||||
import json.Json
|
||||
import http.Client as Http exposing [get, post]
|
||||
import utils.String as Str
|
||||
|
||||
main = {
|
||||
client = Http.get
|
||||
parser = Json.utf8
|
||||
helper = Str.trim
|
||||
|
||||
# Test direct module access
|
||||
result1 = Json.parse
|
||||
|
||||
# Test aliased module access
|
||||
result2 = Http.post
|
||||
|
||||
# Test exposed items (should work without module prefix)
|
||||
result3 = get
|
||||
result4 = post
|
||||
|
||||
# Test multiple qualified access
|
||||
combined = Str.concat
|
||||
|
||||
(
|
||||
client,
|
||||
parser,
|
||||
helper,
|
||||
result1,
|
||||
result2,
|
||||
result3,
|
||||
result4,
|
||||
combined,
|
||||
)
|
||||
}
|
||||
~~~
|
||||
# PROBLEMS
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwModule(1:1-1:7),OpenSquare(1:8-1:9),CloseSquare(1:9-1:10),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
KwImport(3:1-3:7),LowerIdent(3:8-3:12),NoSpaceDotUpperIdent(3:12-3:17),Newline(1:1-1:1),
|
||||
KwImport(4:1-4:7),LowerIdent(4:8-4:12),NoSpaceDotUpperIdent(4:12-4:19),KwAs(4:20-4:22),UpperIdent(4:23-4:27),KwExposing(4:28-4:36),OpenSquare(4:37-4:38),LowerIdent(4:38-4:41),Comma(4:41-4:42),LowerIdent(4:43-4:47),CloseSquare(4:47-4:48),Newline(1:1-1:1),
|
||||
KwImport(5:1-5:7),LowerIdent(5:8-5:13),NoSpaceDotUpperIdent(5:13-5:20),KwAs(5:21-5:23),UpperIdent(5:24-5:27),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
LowerIdent(7:1-7:5),OpAssign(7:6-7:7),OpenCurly(7:8-7:9),Newline(1:1-1:1),
|
||||
LowerIdent(8:5-8:11),OpAssign(8:12-8:13),UpperIdent(8:14-8:18),NoSpaceDotLowerIdent(8:18-8:22),Newline(1:1-1:1),
|
||||
LowerIdent(9:5-9:11),OpAssign(9:12-9:13),UpperIdent(9:14-9:18),NoSpaceDotLowerIdent(9:18-9:23),Newline(1:1-1:1),
|
||||
LowerIdent(10:5-10:11),OpAssign(10:12-10:13),UpperIdent(10:14-10:17),NoSpaceDotLowerIdent(10:17-10:22),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
Newline(12:6-12:32),
|
||||
LowerIdent(13:5-13:12),OpAssign(13:13-13:14),UpperIdent(13:15-13:19),NoSpaceDotLowerIdent(13:19-13:25),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
Newline(15:6-15:33),
|
||||
LowerIdent(16:5-16:12),OpAssign(16:13-16:14),UpperIdent(16:15-16:19),NoSpaceDotLowerIdent(16:19-16:24),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
Newline(18:6-18:61),
|
||||
LowerIdent(19:5-19:12),OpAssign(19:13-19:14),LowerIdent(19:15-19:18),Newline(1:1-1:1),
|
||||
LowerIdent(20:5-20:12),OpAssign(20:13-20:14),LowerIdent(20:15-20:19),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
Newline(22:6-22:37),
|
||||
LowerIdent(23:5-23:13),OpAssign(23:14-23:15),UpperIdent(23:16-23:19),NoSpaceDotLowerIdent(23:19-23:26),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
OpenRound(25:5-25:6),Newline(1:1-1:1),
|
||||
LowerIdent(26:9-26:15),Comma(26:15-26:16),Newline(1:1-1:1),
|
||||
LowerIdent(27:9-27:15),Comma(27:15-27:16),Newline(1:1-1:1),
|
||||
LowerIdent(28:9-28:15),Comma(28:15-28:16),Newline(1:1-1:1),
|
||||
LowerIdent(29:9-29:16),Comma(29:16-29:17),Newline(1:1-1:1),
|
||||
LowerIdent(30:9-30:16),Comma(30:16-30:17),Newline(1:1-1:1),
|
||||
LowerIdent(31:9-31:16),Comma(31:16-31:17),Newline(1:1-1:1),
|
||||
LowerIdent(32:9-32:16),Comma(32:16-32:17),Newline(1:1-1:1),
|
||||
LowerIdent(33:9-33:17),Comma(33:17-33:18),Newline(1:1-1:1),
|
||||
CloseRound(34:5-34:6),Newline(1:1-1:1),
|
||||
CloseCurly(35:1-35:2),EndOfFile(35:2-35:2),
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file (1:1-35:2)
|
||||
(module (1:1-1:10) (exposes (1:8-1:10)))
|
||||
(statements
|
||||
(import (3:1-3:17) ".Json" (qualifier "json"))
|
||||
(import (4:1-4:48)
|
||||
".Client"
|
||||
(qualifier "http")
|
||||
(alias "Http")
|
||||
(exposing
|
||||
(exposed_item (lower_ident "get"))
|
||||
(exposed_item (lower_ident "post"))))
|
||||
(import (5:1-5:27)
|
||||
".String"
|
||||
(qualifier "utils")
|
||||
(alias "Str"))
|
||||
(decl (7:1-35:2)
|
||||
(ident (7:1-7:5) "main")
|
||||
(block (7:8-35:2)
|
||||
(statements
|
||||
(decl (8:5-8:22)
|
||||
(ident (8:5-8:11) "client")
|
||||
(ident (8:14-8:22) "Http" ".get"))
|
||||
(decl (9:5-9:23)
|
||||
(ident (9:5-9:11) "parser")
|
||||
(ident (9:14-9:23) "Json" ".utf8"))
|
||||
(decl (10:5-10:22)
|
||||
(ident (10:5-10:11) "helper")
|
||||
(ident (10:14-10:22) "Str" ".trim"))
|
||||
(decl (13:5-13:25)
|
||||
(ident (13:5-13:12) "result1")
|
||||
(ident (13:15-13:25) "Json" ".parse"))
|
||||
(decl (16:5-16:24)
|
||||
(ident (16:5-16:12) "result2")
|
||||
(ident (16:15-16:24) "Http" ".post"))
|
||||
(decl (19:5-19:18)
|
||||
(ident (19:5-19:12) "result3")
|
||||
(ident (19:15-19:18) "" "get"))
|
||||
(decl (20:5-20:19)
|
||||
(ident (20:5-20:12) "result4")
|
||||
(ident (20:15-20:19) "" "post"))
|
||||
(decl (23:5-23:26)
|
||||
(ident (23:5-23:13) "combined")
|
||||
(ident (23:16-23:26) "Str" ".concat"))
|
||||
(tuple (25:5-34:6)
|
||||
(ident (26:9-26:15) "" "client")
|
||||
(ident (27:9-27:15) "" "parser")
|
||||
(ident (28:9-28:15) "" "helper")
|
||||
(ident (29:9-29:16) "" "result1")
|
||||
(ident (30:9-30:16) "" "result2")
|
||||
(ident (31:9-31:16) "" "result3")
|
||||
(ident (32:9-32:16) "" "result4")
|
||||
(ident (33:9-33:17) "" "combined")))))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
module []
|
||||
|
||||
import json.Json
|
||||
import http.Client as Http exposing [get, post]
|
||||
import utils.String as Str
|
||||
|
||||
main = {
|
||||
client = Http.get
|
||||
parser = Json.utf8
|
||||
helper = Str.trim
|
||||
|
||||
# Test direct module access
|
||||
result1 = Json.parse
|
||||
|
||||
# Test aliased module access
|
||||
result2 = Http.post
|
||||
|
||||
# Test exposed items (should work without module prefix)
|
||||
result3 = get
|
||||
result4 = post
|
||||
|
||||
# Test multiple qualified access
|
||||
combined = Str.concat
|
||||
|
||||
(
|
||||
client,
|
||||
parser,
|
||||
helper,
|
||||
result1,
|
||||
result2,
|
||||
result3,
|
||||
result4,
|
||||
combined,
|
||||
)
|
||||
}
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can_ir
|
||||
(d_let
|
||||
(def_pattern
|
||||
(p_assign (7:1-7:5)
|
||||
(pid 77)
|
||||
(ident "main")))
|
||||
(def_expr
|
||||
(e_block (7:8-35:2)
|
||||
(s_let (8:5-8:22)
|
||||
(p_assign (8:5-8:11)
|
||||
(pid 78)
|
||||
(ident "client"))
|
||||
(e_lookup_external
|
||||
(external_decl (8:14-8:22)
|
||||
(qualified_name "http.Client.get")
|
||||
(module_name "http.Client")
|
||||
(local_name "get")
|
||||
(kind "value")
|
||||
(type_var 79))))
|
||||
(s_let (9:5-9:23)
|
||||
(p_assign (9:5-9:11)
|
||||
(pid 82)
|
||||
(ident "parser"))
|
||||
(e_lookup_external
|
||||
(external_decl (9:14-9:23)
|
||||
(qualified_name "json.Json.utf8")
|
||||
(module_name "json.Json")
|
||||
(local_name "utf8")
|
||||
(kind "value")
|
||||
(type_var 83))))
|
||||
(s_let (10:5-10:22)
|
||||
(p_assign (10:5-10:11)
|
||||
(pid 86)
|
||||
(ident "helper"))
|
||||
(e_lookup_external
|
||||
(external_decl (10:14-10:22)
|
||||
(qualified_name "utils.String.trim")
|
||||
(module_name "utils.String")
|
||||
(local_name "trim")
|
||||
(kind "value")
|
||||
(type_var 87))))
|
||||
(s_let (13:5-13:25)
|
||||
(p_assign (13:5-13:12)
|
||||
(pid 90)
|
||||
(ident "result1"))
|
||||
(e_lookup_external
|
||||
(external_decl (13:15-13:25)
|
||||
(qualified_name "json.Json.parse")
|
||||
(module_name "json.Json")
|
||||
(local_name "parse")
|
||||
(kind "value")
|
||||
(type_var 91))))
|
||||
(s_let (16:5-16:24)
|
||||
(p_assign (16:5-16:12)
|
||||
(pid 94)
|
||||
(ident "result2"))
|
||||
(e_lookup_external
|
||||
(external_decl (16:15-16:24)
|
||||
(qualified_name "http.Client.post")
|
||||
(module_name "http.Client")
|
||||
(local_name "post")
|
||||
(kind "value")
|
||||
(type_var 95))))
|
||||
(s_let (19:5-19:18)
|
||||
(p_assign (19:5-19:12)
|
||||
(pid 98)
|
||||
(ident "result3"))
|
||||
(e_lookup_external
|
||||
(external_decl (19:15-19:18)
|
||||
(qualified_name "http.Client.get")
|
||||
(module_name "http.Client")
|
||||
(local_name "get")
|
||||
(kind "value")
|
||||
(type_var 99))))
|
||||
(s_let (20:5-20:19)
|
||||
(p_assign (20:5-20:12)
|
||||
(pid 102)
|
||||
(ident "result4"))
|
||||
(e_lookup_external
|
||||
(external_decl (20:15-20:19)
|
||||
(qualified_name "http.Client.post")
|
||||
(module_name "http.Client")
|
||||
(local_name "post")
|
||||
(kind "value")
|
||||
(type_var 103))))
|
||||
(s_let (23:5-23:26)
|
||||
(p_assign (23:5-23:13)
|
||||
(pid 106)
|
||||
(ident "combined"))
|
||||
(e_lookup_external
|
||||
(external_decl (23:16-23:26)
|
||||
(qualified_name "utils.String.concat")
|
||||
(module_name "utils.String")
|
||||
(local_name "concat")
|
||||
(kind "value")
|
||||
(type_var 107))))
|
||||
(e_tuple (25:5-34:6)
|
||||
(tuple_var "#118")
|
||||
(elems
|
||||
(e_lookup_local (26:9-26:15) (pid 78))
|
||||
(e_lookup_local (27:9-27:15) (pid 82))
|
||||
(e_lookup_local (28:9-28:15) (pid 86))
|
||||
(e_lookup_local (29:9-29:16) (pid 90))
|
||||
(e_lookup_local (30:9-30:16) (pid 94))
|
||||
(e_lookup_local (31:9-31:16) (pid 98))
|
||||
(e_lookup_local (32:9-32:16) (pid 102))
|
||||
(e_lookup_local (33:9-33:17) (pid 106)))))))
|
||||
(s_import (3:1-3:17)
|
||||
"json.Json"
|
||||
""
|
||||
""
|
||||
(exposes))
|
||||
(s_import (4:1-4:48)
|
||||
"http.Client"
|
||||
""
|
||||
""
|
||||
(exposes (exposed_item "get") (exposed_item "post")))
|
||||
(s_import (5:1-5:27)
|
||||
"utils.String"
|
||||
""
|
||||
""
|
||||
(exposes)))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred_types
|
||||
(defs
|
||||
(def "main" 121 (type "*")))
|
||||
(expressions
|
||||
(expr (7:8-35:2) 120 (type "*"))))
|
||||
~~~
|
67
src/snapshots/can_import_json.md
generated
Normal file
67
src/snapshots/can_import_json.md
generated
Normal file
|
@ -0,0 +1,67 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Import with module-qualified usage
|
||||
type=file
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
module []
|
||||
|
||||
import json.Json
|
||||
|
||||
main = Json.utf8
|
||||
~~~
|
||||
# PROBLEMS
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwModule(1:1-1:7),OpenSquare(1:8-1:9),CloseSquare(1:9-1:10),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
KwImport(3:1-3:7),LowerIdent(3:8-3:12),NoSpaceDotUpperIdent(3:12-3:17),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
LowerIdent(5:1-5:5),OpAssign(5:6-5:7),UpperIdent(5:8-5:12),NoSpaceDotLowerIdent(5:12-5:17),EndOfFile(5:17-5:17),
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file (1:1-5:17)
|
||||
(module (1:1-1:10) (exposes (1:8-1:10)))
|
||||
(statements
|
||||
(import (3:1-3:17) ".Json" (qualifier "json"))
|
||||
(decl (5:1-5:17)
|
||||
(ident (5:1-5:5) "main")
|
||||
(ident (5:8-5:17) "Json" ".utf8"))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can_ir
|
||||
(d_let
|
||||
(def_pattern
|
||||
(p_assign (5:1-5:5)
|
||||
(pid 73)
|
||||
(ident "main")))
|
||||
(def_expr
|
||||
(e_lookup_external
|
||||
(external_decl (5:8-5:17)
|
||||
(qualified_name "json.Json.utf8")
|
||||
(module_name "json.Json")
|
||||
(local_name "utf8")
|
||||
(kind "value")
|
||||
(type_var 74)))))
|
||||
(s_import (3:1-3:17)
|
||||
"json.Json"
|
||||
""
|
||||
""
|
||||
(exposes)))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred_types
|
||||
(defs
|
||||
(def "main" 76 (type "*")))
|
||||
(expressions
|
||||
(expr (5:8-5:17) 75 (type "*"))))
|
||||
~~~
|
70
src/snapshots/can_import_with_alias.md
generated
Normal file
70
src/snapshots/can_import_with_alias.md
generated
Normal file
|
@ -0,0 +1,70 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Import with explicit alias
|
||||
type=file
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
module []
|
||||
|
||||
import json.Json as MyJson
|
||||
|
||||
main = MyJson.decode
|
||||
~~~
|
||||
# PROBLEMS
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwModule(1:1-1:7),OpenSquare(1:8-1:9),CloseSquare(1:9-1:10),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
KwImport(3:1-3:7),LowerIdent(3:8-3:12),NoSpaceDotUpperIdent(3:12-3:17),KwAs(3:18-3:20),UpperIdent(3:21-3:27),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
LowerIdent(5:1-5:5),OpAssign(5:6-5:7),UpperIdent(5:8-5:14),NoSpaceDotLowerIdent(5:14-5:21),EndOfFile(5:21-5:21),
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file (1:1-5:21)
|
||||
(module (1:1-1:10) (exposes (1:8-1:10)))
|
||||
(statements
|
||||
(import (3:1-3:27)
|
||||
".Json"
|
||||
(qualifier "json")
|
||||
(alias "MyJson"))
|
||||
(decl (5:1-5:21)
|
||||
(ident (5:1-5:5) "main")
|
||||
(ident (5:8-5:21) "MyJson" ".decode"))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can_ir
|
||||
(d_let
|
||||
(def_pattern
|
||||
(p_assign (5:1-5:5)
|
||||
(pid 73)
|
||||
(ident "main")))
|
||||
(def_expr
|
||||
(e_lookup_external
|
||||
(external_decl (5:8-5:21)
|
||||
(qualified_name "json.Json.decode")
|
||||
(module_name "json.Json")
|
||||
(local_name "decode")
|
||||
(kind "value")
|
||||
(type_var 74)))))
|
||||
(s_import (3:1-3:27)
|
||||
"json.Json"
|
||||
""
|
||||
""
|
||||
(exposes)))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred_types
|
||||
(defs
|
||||
(def "main" 76 (type "*")))
|
||||
(expressions
|
||||
(expr (5:8-5:21) 75 (type "*"))))
|
||||
~~~
|
2
src/snapshots/can_two_decls.md
generated
2
src/snapshots/can_two_decls.md
generated
|
@ -69,7 +69,7 @@ NO CHANGE
|
|||
(def_expr
|
||||
(e_binop (4:5-4:10)
|
||||
"add"
|
||||
(e_lookup (4:5-4:6) (pid 72))
|
||||
(e_lookup_local (4:5-4:6) (pid 72))
|
||||
(e_int (4:9-4:10)
|
||||
(int_var 80)
|
||||
(precision_var 79)
|
||||
|
|
12
src/snapshots/can_var_scoping_regular_var.md
generated
12
src/snapshots/can_var_scoping_regular_var.md
generated
|
@ -177,7 +177,7 @@ NO CHANGE
|
|||
(pid 77)
|
||||
(e_binop (9:11-10:8)
|
||||
"add"
|
||||
(e_lookup (9:11-9:17) (pid 77))
|
||||
(e_lookup_local (9:11-9:17) (pid 77))
|
||||
(e_int (9:20-9:21)
|
||||
(int_var 86)
|
||||
(precision_var 85)
|
||||
|
@ -188,7 +188,7 @@ NO CHANGE
|
|||
(pid 82)
|
||||
(e_binop (10:11-13:12)
|
||||
"add"
|
||||
(e_lookup (10:11-10:17) (pid 82))
|
||||
(e_lookup_local (10:11-10:17) (pid 82))
|
||||
(e_int (10:20-10:22)
|
||||
(int_var 92)
|
||||
(precision_var 91)
|
||||
|
@ -208,18 +208,18 @@ NO CHANGE
|
|||
(s_reassign (15:3-15:9)
|
||||
(pid 82)
|
||||
(e_runtime_error (15:3-15:9) "var_across_function_boundary"))
|
||||
(e_lookup (16:3-16:9) (pid 77)))))
|
||||
(e_lookup_local (16:3-16:9) (pid 77)))))
|
||||
(s_let (19:2-19:25)
|
||||
(p_assign (19:2-19:8)
|
||||
(pid 108)
|
||||
(ident "result"))
|
||||
(e_call (19:11-19:25)
|
||||
(e_lookup (19:11-19:21) (pid 96))
|
||||
(e_lookup_local (19:11-19:21) (pid 96))
|
||||
(e_runtime_error (1:1-1:1) "not_implemented")))
|
||||
(e_binop (20:2-21:2)
|
||||
"add"
|
||||
(e_lookup (20:2-20:8) (pid 82))
|
||||
(e_lookup (20:11-20:17) (pid 108))))))))
|
||||
(e_lookup_local (20:2-20:8) (pid 82))
|
||||
(e_lookup_local (20:11-20:17) (pid 108))))))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
12
src/snapshots/can_var_scoping_var_idents.md
generated
12
src/snapshots/can_var_scoping_var_idents.md
generated
|
@ -85,7 +85,7 @@ NO CHANGE
|
|||
(p_assign (5:2-5:5)
|
||||
(pid 74)
|
||||
(ident "sum"))
|
||||
(e_lookup (5:8-5:13) (pid 73)))
|
||||
(e_lookup_local (5:8-5:13) (pid 73)))
|
||||
(s_var (6:2-8:6)
|
||||
(pid 82)
|
||||
(p_assign (6:2-8:6)
|
||||
|
@ -93,7 +93,7 @@ NO CHANGE
|
|||
(ident "sum_"))
|
||||
(e_binop (6:13-8:6)
|
||||
"mul"
|
||||
(e_lookup (6:13-6:18) (pid 73))
|
||||
(e_lookup_local (6:13-6:18) (pid 73))
|
||||
(e_int (6:21-6:22)
|
||||
(int_var 79)
|
||||
(precision_var 78)
|
||||
|
@ -104,12 +104,12 @@ NO CHANGE
|
|||
(pid 82)
|
||||
(e_binop (8:9-9:5)
|
||||
"add"
|
||||
(e_lookup (8:9-8:13) (pid 82))
|
||||
(e_lookup (8:16-8:19) (pid 74))))
|
||||
(e_lookup_local (8:9-8:13) (pid 82))
|
||||
(e_lookup_local (8:16-8:19) (pid 74))))
|
||||
(e_binop (9:2-10:2)
|
||||
"add"
|
||||
(e_lookup (9:2-9:5) (pid 74))
|
||||
(e_lookup (9:8-9:12) (pid 82))))))))
|
||||
(e_lookup_local (9:2-9:5) (pid 74))
|
||||
(e_lookup_local (9:8-9:12) (pid 82))))))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
|
@ -138,7 +138,7 @@ NO CHANGE
|
|||
(literal "15")
|
||||
(value "TODO")
|
||||
(bound "u8")))
|
||||
(e_lookup (8:2-8:4) (pid 77))))))
|
||||
(e_lookup_local (8:2-8:4) (pid 77))))))
|
||||
(d_let
|
||||
(def_pattern
|
||||
(p_assign (11:1-11:7)
|
||||
|
@ -146,7 +146,7 @@ NO CHANGE
|
|||
(ident "result")))
|
||||
(def_expr
|
||||
(e_call (11:10-11:27)
|
||||
(e_lookup (11:10-11:23) (pid 72))
|
||||
(e_lookup_local (11:10-11:23) (pid 72))
|
||||
(e_runtime_error (1:1-1:1) "not_implemented")))))
|
||||
~~~
|
||||
# TYPES
|
||||
|
|
4
src/snapshots/crash_and_ellipsis_test.md
generated
4
src/snapshots/crash_and_ellipsis_test.md
generated
|
@ -267,7 +267,7 @@ result3 = testCrashSimple(42)
|
|||
(ident "result2")))
|
||||
(def_expr
|
||||
(e_call (17:15-17:28)
|
||||
(e_lookup (17:15-17:24) (pid 89))
|
||||
(e_lookup_local (17:15-17:24) (pid 89))
|
||||
(e_int (17:25-17:27)
|
||||
(int_var 127)
|
||||
(precision_var 126)
|
||||
|
@ -281,7 +281,7 @@ result3 = testCrashSimple(42)
|
|||
(ident "result3")))
|
||||
(def_expr
|
||||
(e_call (18:15-18:34)
|
||||
(e_lookup (18:15-18:30) (pid 104))
|
||||
(e_lookup_local (18:15-18:30) (pid 104))
|
||||
(e_int (18:31-18:33)
|
||||
(int_var 134)
|
||||
(precision_var 133)
|
||||
|
|
72
src/snapshots/exposed_items_test.md
generated
Normal file
72
src/snapshots/exposed_items_test.md
generated
Normal file
|
@ -0,0 +1,72 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Import with exposing syntax test
|
||||
type=file
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
module [main]
|
||||
|
||||
import pf.Stdout exposing [line!, write!]
|
||||
|
||||
main = 42
|
||||
~~~
|
||||
# PROBLEMS
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwModule(1:1-1:7),OpenSquare(1:8-1:9),LowerIdent(1:9-1:13),CloseSquare(1:13-1:14),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
KwImport(3:1-3:7),LowerIdent(3:8-3:10),NoSpaceDotUpperIdent(3:10-3:17),KwExposing(3:18-3:26),OpenSquare(3:27-3:28),LowerIdent(3:28-3:33),Comma(3:33-3:34),LowerIdent(3:35-3:41),CloseSquare(3:41-3:42),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
LowerIdent(5:1-5:5),OpAssign(5:6-5:7),Int(5:8-5:10),EndOfFile(5:10-5:10),
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file (1:1-5:10)
|
||||
(module (1:1-1:14)
|
||||
(exposes (1:8-1:14) (exposed_item (lower_ident "main"))))
|
||||
(statements
|
||||
(import (3:1-3:42)
|
||||
".Stdout"
|
||||
(qualifier "pf")
|
||||
(exposing
|
||||
(exposed_item (lower_ident "line!"))
|
||||
(exposed_item (lower_ident "write!"))))
|
||||
(decl (5:1-5:10)
|
||||
(ident (5:1-5:5) "main")
|
||||
(int (5:8-5:10) "42"))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can_ir
|
||||
(d_let
|
||||
(def_pattern
|
||||
(p_assign (5:1-5:5)
|
||||
(pid 75)
|
||||
(ident "main")))
|
||||
(def_expr
|
||||
(e_int (5:8-5:10)
|
||||
(int_var 77)
|
||||
(precision_var 76)
|
||||
(literal "42")
|
||||
(value "TODO")
|
||||
(bound "u8"))))
|
||||
(s_import (3:1-3:42)
|
||||
"pf.Stdout"
|
||||
""
|
||||
""
|
||||
(exposes (exposed_item "line!") (exposed_item "write!"))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred_types
|
||||
(defs
|
||||
(def "main" 79 (type "Num(Int(*))")))
|
||||
(expressions
|
||||
(expr (5:8-5:10) 78 (type "Num(Int(*))"))))
|
||||
~~~
|
|
@ -66,7 +66,7 @@ CloseCurly(5:1-5:2),EndOfFile(5:2-5:2),
|
|||
(ident "y"))
|
||||
(e_binop (3:9-4:6)
|
||||
"add"
|
||||
(e_lookup (3:9-3:10) (pid 72))
|
||||
(e_lookup_local (3:9-3:10) (pid 72))
|
||||
(e_int (3:13-3:14)
|
||||
(int_var 80)
|
||||
(precision_var 79)
|
||||
|
@ -75,7 +75,7 @@ CloseCurly(5:1-5:2),EndOfFile(5:2-5:2),
|
|||
(bound "u8"))))
|
||||
(e_binop (4:5-5:2)
|
||||
"mul"
|
||||
(e_lookup (4:5-4:6) (pid 77))
|
||||
(e_lookup_local (4:5-4:6) (pid 77))
|
||||
(e_int (4:9-4:10)
|
||||
(int_var 86)
|
||||
(precision_var 85)
|
||||
|
|
|
@ -35,7 +35,7 @@ NO CHANGE
|
|||
(ident "x")))
|
||||
(e_binop (1:5-1:10)
|
||||
"add"
|
||||
(e_lookup (1:5-1:6) (pid 72))
|
||||
(e_lookup_local (1:5-1:6) (pid 72))
|
||||
(e_int (1:9-1:10)
|
||||
(int_var 75)
|
||||
(precision_var 74)
|
||||
|
|
|
@ -363,7 +363,7 @@ CloseCurly(19:1-19:2),EndOfFile(19:2-19:2),
|
|||
(tuple_var "#164")
|
||||
(elems
|
||||
(e_call (14:11-14:21)
|
||||
(e_lookup (14:11-14:18) (pid 72))
|
||||
(e_lookup_local (14:11-14:18) (pid 72))
|
||||
(e_int (14:19-14:20)
|
||||
(int_var 148)
|
||||
(precision_var 147)
|
||||
|
@ -399,9 +399,9 @@ CloseCurly(19:1-19:2),EndOfFile(19:2-19:2),
|
|||
(e_tuple (15:14-15:23)
|
||||
(tuple_var "#171")
|
||||
(elems
|
||||
(e_lookup (15:15-15:16) (pid 78))
|
||||
(e_lookup (15:18-15:19) (pid 83))
|
||||
(e_lookup (15:21-15:22) (pid 88)))))
|
||||
(e_lookup_local (15:15-15:16) (pid 78))
|
||||
(e_lookup_local (15:18-15:19) (pid 83))
|
||||
(e_lookup_local (15:21-15:22) (pid 88)))))
|
||||
(s_let (16:2-16:31)
|
||||
(p_assign (16:2-16:13)
|
||||
(pid 174)
|
||||
|
@ -416,7 +416,7 @@ CloseCurly(19:1-19:2),EndOfFile(19:2-19:2),
|
|||
(ident "n")))
|
||||
(e_binop (16:21-16:27)
|
||||
"add"
|
||||
(e_lookup (16:21-16:22) (pid 175))
|
||||
(e_lookup_local (16:21-16:22) (pid 175))
|
||||
(e_int (16:25-16:26)
|
||||
(int_var 178)
|
||||
(precision_var 177)
|
||||
|
@ -429,7 +429,7 @@ CloseCurly(19:1-19:2),EndOfFile(19:2-19:2),
|
|||
(literal "42")
|
||||
(value "TODO")
|
||||
(bound "u8")))))
|
||||
(e_lookup (18:2-18:7) (pid 93)))
|
||||
(e_lookup_local (18:2-18:7) (pid 93)))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
129
src/snapshots/external_decl_lookup.md
generated
Normal file
129
src/snapshots/external_decl_lookup.md
generated
Normal file
|
@ -0,0 +1,129 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=External declaration lookup from json module
|
||||
type=file
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
app [main!] { pf: platform "../basic-cli/platform.roc" }
|
||||
|
||||
import pf.Stdout
|
||||
import json.Json
|
||||
|
||||
main! = |_| {
|
||||
# This should create an external declaration for json.Json.utf8
|
||||
result = Json.utf8("Hello from external module!")
|
||||
Stdout.line!(result)
|
||||
}
|
||||
~~~
|
||||
# PROBLEMS
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwApp(1:1-1:4),OpenSquare(1:5-1:6),LowerIdent(1:6-1:11),CloseSquare(1:11-1:12),OpenCurly(1:13-1:14),LowerIdent(1:15-1:17),OpColon(1:17-1:18),KwPlatform(1:19-1:27),StringStart(1:28-1:29),StringPart(1:29-1:54),StringEnd(1:54-1:55),CloseCurly(1:56-1:57),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
KwImport(3:1-3:7),LowerIdent(3:8-3:10),NoSpaceDotUpperIdent(3:10-3:17),Newline(1:1-1:1),
|
||||
KwImport(4:1-4:7),LowerIdent(4:8-4:12),NoSpaceDotUpperIdent(4:12-4:17),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
LowerIdent(6:1-6:6),OpAssign(6:7-6:8),OpBar(6:9-6:10),Underscore(6:10-6:11),OpBar(6:11-6:12),OpenCurly(6:13-6:14),Newline(1:1-1:1),
|
||||
Newline(7:6-7:68),
|
||||
LowerIdent(8:5-8:11),OpAssign(8:12-8:13),UpperIdent(8:14-8:18),NoSpaceDotLowerIdent(8:18-8:23),NoSpaceOpenRound(8:23-8:24),StringStart(8:24-8:25),StringPart(8:25-8:52),StringEnd(8:52-8:53),CloseRound(8:53-8:54),Newline(1:1-1:1),
|
||||
UpperIdent(9:5-9:11),NoSpaceDotLowerIdent(9:11-9:17),NoSpaceOpenRound(9:17-9:18),LowerIdent(9:18-9:24),CloseRound(9:24-9:25),Newline(1:1-1:1),
|
||||
CloseCurly(10:1-10:2),EndOfFile(10:2-10:2),
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file (1:1-10:2)
|
||||
(app (1:1-1:57)
|
||||
(provides (1:6-1:12) (exposed_item (lower_ident "main!")))
|
||||
(record_field (1:15-1:57)
|
||||
"pf"
|
||||
(string (1:28-1:55) (string_part (1:29-1:54) "../basic-cli/platform.roc")))
|
||||
(packages (1:13-1:57)
|
||||
(record_field (1:15-1:57)
|
||||
"pf"
|
||||
(string (1:28-1:55) (string_part (1:29-1:54) "../basic-cli/platform.roc")))))
|
||||
(statements
|
||||
(import (3:1-3:17) ".Stdout" (qualifier "pf"))
|
||||
(import (4:1-4:17) ".Json" (qualifier "json"))
|
||||
(decl (6:1-10:2)
|
||||
(ident (6:1-6:6) "main!")
|
||||
(lambda (6:9-10:2)
|
||||
(args (underscore))
|
||||
(block (6:13-10:2)
|
||||
(statements
|
||||
(decl (8:5-8:54)
|
||||
(ident (8:5-8:11) "result")
|
||||
(apply (8:14-8:54)
|
||||
(ident (8:14-8:23) "Json" ".utf8")
|
||||
(string (8:24-8:53) (string_part (8:25-8:52) "Hello from external module!"))))
|
||||
(apply (9:5-9:25)
|
||||
(ident (9:5-9:17) "Stdout" ".line!")
|
||||
(ident (9:18-9:24) "" "result"))))))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
app [main!] { pf: platform "../basic-cli/platform.roc" }
|
||||
|
||||
import pf.Stdout
|
||||
import json.Json
|
||||
|
||||
main! = |_| {
|
||||
# This should create an external declaration for json.Json.utf8
|
||||
result = Json.utf8("Hello from external module!")
|
||||
Stdout.line!(result)
|
||||
}
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can_ir
|
||||
(d_let
|
||||
(def_pattern
|
||||
(p_assign (6:1-6:6)
|
||||
(pid 74)
|
||||
(ident "main!")))
|
||||
(def_expr
|
||||
(e_lambda (6:9-10:2)
|
||||
(args (p_underscore (6:10-6:11) (pid 75)))
|
||||
(e_block (6:13-10:2)
|
||||
(s_let (8:5-8:54)
|
||||
(p_assign (8:5-8:11)
|
||||
(pid 76)
|
||||
(ident "result"))
|
||||
(e_call (8:14-8:54)
|
||||
(e_lookup_external
|
||||
(external_decl (8:14-8:23)
|
||||
(qualified_name "json.Json.utf8")
|
||||
(module_name "json.Json")
|
||||
(local_name "utf8")
|
||||
(kind "value")
|
||||
(type_var 77)))
|
||||
(e_string (8:24-8:53) (e_literal (8:25-8:52) "Hello from external module!"))))
|
||||
(e_call (9:5-9:25)
|
||||
(e_lookup_external
|
||||
(external_decl (9:5-9:17)
|
||||
(qualified_name "pf.Stdout.line!")
|
||||
(module_name "pf.Stdout")
|
||||
(local_name "line!")
|
||||
(kind "value")
|
||||
(type_var 83)))
|
||||
(e_lookup_local (9:18-9:24) (pid 76)))))))
|
||||
(s_import (3:1-3:17)
|
||||
"pf.Stdout"
|
||||
""
|
||||
""
|
||||
(exposes))
|
||||
(s_import (4:1-4:17)
|
||||
"json.Json"
|
||||
""
|
||||
""
|
||||
(exposes)))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred_types
|
||||
(defs
|
||||
(def "main!" 89 (type "*")))
|
||||
(expressions
|
||||
(expr (6:9-10:2) 88 (type "*"))))
|
||||
~~~
|
34
src/snapshots/external_lookup_expr.md
generated
Normal file
34
src/snapshots/external_lookup_expr.md
generated
Normal file
|
@ -0,0 +1,34 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=External declaration lookup expression
|
||||
type=expr
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
Json.utf8
|
||||
~~~
|
||||
# PROBLEMS
|
||||
**UNDEFINED VARIABLE**
|
||||
Nothing is named `utf8` in this scope.
|
||||
Is there an `import` or `exposing` missing up-top?
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
UpperIdent(1:1-1:5),NoSpaceDotLowerIdent(1:5-1:10),EndOfFile(1:10-1:10),
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(ident (1:1-1:10) "Json" ".utf8")
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(e_runtime_error (1:1-1:10) "ident_not_in_scope")
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr 73 (type "Error"))
|
||||
~~~
|
23
src/snapshots/hello_world.md
generated
23
src/snapshots/hello_world.md
generated
|
@ -12,13 +12,7 @@ import pf.Stdout
|
|||
main! = |_| Stdout.line!("Hello, world!")
|
||||
~~~
|
||||
# PROBLEMS
|
||||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: top-level import
|
||||
|
||||
**UNDEFINED VARIABLE**
|
||||
Nothing is named `line!` in this scope.
|
||||
Is there an `import` or `exposing` missing up-top?
|
||||
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwApp(1:1-1:4),OpenSquare(1:5-1:6),LowerIdent(1:6-1:11),CloseSquare(1:11-1:12),OpenCurly(1:13-1:14),LowerIdent(1:15-1:17),OpColon(1:17-1:18),KwPlatform(1:19-1:27),StringStart(1:28-1:29),StringPart(1:29-1:54),StringEnd(1:54-1:55),CloseCurly(1:56-1:57),Newline(1:1-1:1),
|
||||
|
@ -65,8 +59,19 @@ NO CHANGE
|
|||
(e_lambda (5:9-5:42)
|
||||
(args (p_underscore (5:10-5:11) (pid 74)))
|
||||
(e_call (5:13-5:42)
|
||||
(e_runtime_error (5:13-5:25) "ident_not_in_scope")
|
||||
(e_string (5:26-5:41) (e_literal (5:27-5:40) "Hello, world!")))))))
|
||||
(e_lookup_external
|
||||
(external_decl (5:13-5:25)
|
||||
(qualified_name "pf.Stdout.line!")
|
||||
(module_name "pf.Stdout")
|
||||
(local_name "line!")
|
||||
(kind "value")
|
||||
(type_var 75)))
|
||||
(e_string (5:26-5:41) (e_literal (5:27-5:40) "Hello, world!"))))))
|
||||
(s_import (3:1-3:17)
|
||||
"pf.Stdout"
|
||||
""
|
||||
""
|
||||
(exposes)))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
22
src/snapshots/hello_world_with_block.md
generated
22
src/snapshots/hello_world_with_block.md
generated
|
@ -19,13 +19,6 @@ main! = |_| {
|
|||
}
|
||||
~~~
|
||||
# PROBLEMS
|
||||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: top-level import
|
||||
|
||||
**UNDEFINED VARIABLE**
|
||||
Nothing is named `line!` in this scope.
|
||||
Is there an `import` or `exposing` missing up-top?
|
||||
|
||||
**UNUSED VARIABLE**
|
||||
Variable ``world`` is not used anywhere in your code.
|
||||
|
||||
|
@ -101,8 +94,19 @@ NO CHANGE
|
|||
(ident "world"))
|
||||
(e_string (9:10-9:17) (e_literal (9:11-9:16) "World")))
|
||||
(e_call (11:2-11:31)
|
||||
(e_runtime_error (11:2-11:14) "ident_not_in_scope")
|
||||
(e_string (11:15-11:30) (e_literal (11:16-11:29) "Hello, world!"))))))))
|
||||
(e_lookup_external
|
||||
(external_decl (11:2-11:14)
|
||||
(qualified_name "pf.Stdout.line!")
|
||||
(module_name "pf.Stdout")
|
||||
(local_name "line!")
|
||||
(kind "value")
|
||||
(type_var 79)))
|
||||
(e_string (11:15-11:30) (e_literal (11:16-11:29) "Hello, world!")))))))
|
||||
(s_import (6:1-6:17)
|
||||
"pf.Stdout"
|
||||
""
|
||||
""
|
||||
(exposes)))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
132
src/snapshots/import_exposing_alias.md
generated
Normal file
132
src/snapshots/import_exposing_alias.md
generated
Normal file
|
@ -0,0 +1,132 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Import with exposing clause using aliases
|
||||
type=file
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
module [main]
|
||||
|
||||
import json.Json exposing [decode as fromJson, encode as toJson]
|
||||
|
||||
main = {
|
||||
data = { name: "Bob", age: 25 }
|
||||
encoded = toJson(data)
|
||||
decoded = fromJson(encoded)
|
||||
decoded
|
||||
}
|
||||
~~~
|
||||
# PROBLEMS
|
||||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: canonicalize record expression
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwModule(1:1-1:7),OpenSquare(1:8-1:9),LowerIdent(1:9-1:13),CloseSquare(1:13-1:14),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
KwImport(3:1-3:7),LowerIdent(3:8-3:12),NoSpaceDotUpperIdent(3:12-3:17),KwExposing(3:18-3:26),OpenSquare(3:27-3:28),LowerIdent(3:28-3:34),KwAs(3:35-3:37),LowerIdent(3:38-3:46),Comma(3:46-3:47),LowerIdent(3:48-3:54),KwAs(3:55-3:57),LowerIdent(3:58-3:64),CloseSquare(3:64-3:65),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
LowerIdent(5:1-5:5),OpAssign(5:6-5:7),OpenCurly(5:8-5:9),Newline(1:1-1:1),
|
||||
LowerIdent(6:2-6:6),OpAssign(6:7-6:8),OpenCurly(6:9-6:10),LowerIdent(6:11-6:15),OpColon(6:15-6:16),StringStart(6:17-6:18),StringPart(6:18-6:21),StringEnd(6:21-6:22),Comma(6:22-6:23),LowerIdent(6:24-6:27),OpColon(6:27-6:28),Int(6:29-6:31),CloseCurly(6:32-6:33),Newline(1:1-1:1),
|
||||
LowerIdent(7:2-7:9),OpAssign(7:10-7:11),LowerIdent(7:12-7:18),NoSpaceOpenRound(7:18-7:19),LowerIdent(7:19-7:23),CloseRound(7:23-7:24),Newline(1:1-1:1),
|
||||
LowerIdent(8:2-8:9),OpAssign(8:10-8:11),LowerIdent(8:12-8:20),NoSpaceOpenRound(8:20-8:21),LowerIdent(8:21-8:28),CloseRound(8:28-8:29),Newline(1:1-1:1),
|
||||
LowerIdent(9:2-9:9),Newline(1:1-1:1),
|
||||
CloseCurly(10:1-10:2),EndOfFile(10:2-10:2),
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file (1:1-10:2)
|
||||
(module (1:1-1:14)
|
||||
(exposes (1:8-1:14) (exposed_item (lower_ident "main"))))
|
||||
(statements
|
||||
(import (3:1-3:65)
|
||||
".Json"
|
||||
(qualifier "json")
|
||||
(exposing
|
||||
(exposed_item (lower_ident "decode" "fromJson"))
|
||||
(exposed_item (lower_ident "encode" "toJson"))))
|
||||
(decl (5:1-10:2)
|
||||
(ident (5:1-5:5) "main")
|
||||
(block (5:8-10:2)
|
||||
(statements
|
||||
(decl (6:2-6:33)
|
||||
(ident (6:2-6:6) "data")
|
||||
(record (6:9-6:33)
|
||||
(field
|
||||
"name"
|
||||
(string (6:17-6:22) (string_part (6:18-6:21) "Bob")))
|
||||
(field "age" (int (6:29-6:31) "25"))))
|
||||
(decl (7:2-7:24)
|
||||
(ident (7:2-7:9) "encoded")
|
||||
(apply (7:12-7:24)
|
||||
(ident (7:12-7:18) "" "toJson")
|
||||
(ident (7:19-7:23) "" "data")))
|
||||
(decl (8:2-8:29)
|
||||
(ident (8:2-8:9) "decoded")
|
||||
(apply (8:12-8:29)
|
||||
(ident (8:12-8:20) "" "fromJson")
|
||||
(ident (8:21-8:28) "" "encoded")))
|
||||
(ident (9:2-9:9) "" "decoded"))))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can_ir
|
||||
(d_let
|
||||
(def_pattern
|
||||
(p_assign (5:1-5:5)
|
||||
(pid 75)
|
||||
(ident "main")))
|
||||
(def_expr
|
||||
(e_block (5:8-10:2)
|
||||
(s_let (6:2-6:33)
|
||||
(p_assign (6:2-6:6)
|
||||
(pid 76)
|
||||
(ident "data"))
|
||||
(e_runtime_error (1:1-1:1) "not_implemented"))
|
||||
(s_let (7:2-7:24)
|
||||
(p_assign (7:2-7:9)
|
||||
(pid 80)
|
||||
(ident "encoded"))
|
||||
(e_call (7:12-7:24)
|
||||
(e_lookup_external
|
||||
(external_decl (7:12-7:18)
|
||||
(qualified_name "json.Json.encode")
|
||||
(module_name "json.Json")
|
||||
(local_name "toJson")
|
||||
(kind "value")
|
||||
(type_var 81)))
|
||||
(e_lookup_local (7:19-7:23) (pid 76))))
|
||||
(s_let (8:2-8:29)
|
||||
(p_assign (8:2-8:9)
|
||||
(pid 86)
|
||||
(ident "decoded"))
|
||||
(e_call (8:12-8:29)
|
||||
(e_lookup_external
|
||||
(external_decl (8:12-8:20)
|
||||
(qualified_name "json.Json.decode")
|
||||
(module_name "json.Json")
|
||||
(local_name "fromJson")
|
||||
(kind "value")
|
||||
(type_var 87)))
|
||||
(e_lookup_local (8:21-8:28) (pid 80))))
|
||||
(e_lookup_local (9:2-9:9) (pid 86)))))
|
||||
(s_import (3:1-3:65)
|
||||
"json.Json"
|
||||
""
|
||||
""
|
||||
(exposes
|
||||
(exposed_item "decode" "fromJson")
|
||||
(exposed_item "encode" "toJson"))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred_types
|
||||
(defs
|
||||
(def "main" 94 (type "*")))
|
||||
(expressions
|
||||
(expr (5:8-10:2) 93 (type "*"))))
|
||||
~~~
|
139
src/snapshots/import_exposing_basic.md
generated
Normal file
139
src/snapshots/import_exposing_basic.md
generated
Normal file
|
@ -0,0 +1,139 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Import with exposing clause and usage of exposed items
|
||||
type=file
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
module [main]
|
||||
|
||||
import json.Json exposing [decode, encode]
|
||||
|
||||
main = {
|
||||
data = { name: "Alice", age: 30 }
|
||||
encoded = encode(data)
|
||||
decoded = decode(encoded)
|
||||
decoded
|
||||
}
|
||||
~~~
|
||||
# PROBLEMS
|
||||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: canonicalize record expression
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwModule(1:1-1:7),OpenSquare(1:8-1:9),LowerIdent(1:9-1:13),CloseSquare(1:13-1:14),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
KwImport(3:1-3:7),LowerIdent(3:8-3:12),NoSpaceDotUpperIdent(3:12-3:17),KwExposing(3:18-3:26),OpenSquare(3:27-3:28),LowerIdent(3:28-3:34),Comma(3:34-3:35),LowerIdent(3:36-3:42),CloseSquare(3:42-3:43),Newline(1:1-1:1),
|
||||
Newline(1:1-1:1),
|
||||
LowerIdent(5:1-5:5),OpAssign(5:6-5:7),OpenCurly(5:8-5:9),Newline(1:1-1:1),
|
||||
LowerIdent(6:5-6:9),OpAssign(6:10-6:11),OpenCurly(6:12-6:13),LowerIdent(6:14-6:18),OpColon(6:18-6:19),StringStart(6:20-6:21),StringPart(6:21-6:26),StringEnd(6:26-6:27),Comma(6:27-6:28),LowerIdent(6:29-6:32),OpColon(6:32-6:33),Int(6:34-6:36),CloseCurly(6:37-6:38),Newline(1:1-1:1),
|
||||
LowerIdent(7:5-7:12),OpAssign(7:13-7:14),LowerIdent(7:15-7:21),NoSpaceOpenRound(7:21-7:22),LowerIdent(7:22-7:26),CloseRound(7:26-7:27),Newline(1:1-1:1),
|
||||
LowerIdent(8:5-8:12),OpAssign(8:13-8:14),LowerIdent(8:15-8:21),NoSpaceOpenRound(8:21-8:22),LowerIdent(8:22-8:29),CloseRound(8:29-8:30),Newline(1:1-1:1),
|
||||
LowerIdent(9:5-9:12),Newline(1:1-1:1),
|
||||
CloseCurly(10:1-10:2),EndOfFile(10:2-10:2),
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file (1:1-10:2)
|
||||
(module (1:1-1:14)
|
||||
(exposes (1:8-1:14) (exposed_item (lower_ident "main"))))
|
||||
(statements
|
||||
(import (3:1-3:43)
|
||||
".Json"
|
||||
(qualifier "json")
|
||||
(exposing
|
||||
(exposed_item (lower_ident "decode"))
|
||||
(exposed_item (lower_ident "encode"))))
|
||||
(decl (5:1-10:2)
|
||||
(ident (5:1-5:5) "main")
|
||||
(block (5:8-10:2)
|
||||
(statements
|
||||
(decl (6:5-6:38)
|
||||
(ident (6:5-6:9) "data")
|
||||
(record (6:12-6:38)
|
||||
(field
|
||||
"name"
|
||||
(string (6:20-6:27) (string_part (6:21-6:26) "Alice")))
|
||||
(field "age" (int (6:34-6:36) "30"))))
|
||||
(decl (7:5-7:27)
|
||||
(ident (7:5-7:12) "encoded")
|
||||
(apply (7:15-7:27)
|
||||
(ident (7:15-7:21) "" "encode")
|
||||
(ident (7:22-7:26) "" "data")))
|
||||
(decl (8:5-8:30)
|
||||
(ident (8:5-8:12) "decoded")
|
||||
(apply (8:15-8:30)
|
||||
(ident (8:15-8:21) "" "decode")
|
||||
(ident (8:22-8:29) "" "encoded")))
|
||||
(ident (9:5-9:12) "" "decoded"))))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
module [main]
|
||||
|
||||
import json.Json exposing [decode, encode]
|
||||
|
||||
main = {
|
||||
data = { name: "Alice", age: 30 }
|
||||
encoded = encode(data)
|
||||
decoded = decode(encoded)
|
||||
decoded
|
||||
}
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can_ir
|
||||
(d_let
|
||||
(def_pattern
|
||||
(p_assign (5:1-5:5)
|
||||
(pid 75)
|
||||
(ident "main")))
|
||||
(def_expr
|
||||
(e_block (5:8-10:2)
|
||||
(s_let (6:5-6:38)
|
||||
(p_assign (6:5-6:9)
|
||||
(pid 76)
|
||||
(ident "data"))
|
||||
(e_runtime_error (1:1-1:1) "not_implemented"))
|
||||
(s_let (7:5-7:27)
|
||||
(p_assign (7:5-7:12)
|
||||
(pid 80)
|
||||
(ident "encoded"))
|
||||
(e_call (7:15-7:27)
|
||||
(e_lookup_external
|
||||
(external_decl (7:15-7:21)
|
||||
(qualified_name "json.Json.encode")
|
||||
(module_name "json.Json")
|
||||
(local_name "encode")
|
||||
(kind "value")
|
||||
(type_var 81)))
|
||||
(e_lookup_local (7:22-7:26) (pid 76))))
|
||||
(s_let (8:5-8:30)
|
||||
(p_assign (8:5-8:12)
|
||||
(pid 86)
|
||||
(ident "decoded"))
|
||||
(e_call (8:15-8:30)
|
||||
(e_lookup_external
|
||||
(external_decl (8:15-8:21)
|
||||
(qualified_name "json.Json.decode")
|
||||
(module_name "json.Json")
|
||||
(local_name "decode")
|
||||
(kind "value")
|
||||
(type_var 87)))
|
||||
(e_lookup_local (8:22-8:29) (pid 80))))
|
||||
(e_lookup_local (9:5-9:12) (pid 86)))))
|
||||
(s_import (3:1-3:43)
|
||||
"json.Json"
|
||||
""
|
||||
""
|
||||
(exposes (exposed_item "decode") (exposed_item "encode"))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred_types
|
||||
(defs
|
||||
(def "main" 94 (type "*")))
|
||||
(expressions
|
||||
(expr (5:8-10:2) 93 (type "*"))))
|
||||
~~~
|
20
src/snapshots/lambda_parameter_unused.md
generated
20
src/snapshots/lambda_parameter_unused.md
generated
|
@ -246,7 +246,7 @@ main! = |_| {
|
|||
(ident "_factor")))
|
||||
(e_binop (9:22-12:8)
|
||||
"mul"
|
||||
(e_lookup (9:22-9:29) (pid 92))
|
||||
(e_lookup_local (9:22-9:29) (pid 92))
|
||||
(e_int (9:32-9:33)
|
||||
(int_var 96)
|
||||
(precision_var 95)
|
||||
|
@ -297,7 +297,7 @@ main! = |_| {
|
|||
(ident "value")))
|
||||
(e_binop (17:18-19:6)
|
||||
"mul"
|
||||
(e_lookup (17:18-17:23) (pid 125))
|
||||
(e_lookup_local (17:18-17:23) (pid 125))
|
||||
(e_int (17:26-17:27)
|
||||
(int_var 128)
|
||||
(precision_var 127)
|
||||
|
@ -325,7 +325,7 @@ main! = |_| {
|
|||
(pid 140)
|
||||
(ident "result1"))
|
||||
(e_call (20:15-20:21)
|
||||
(e_lookup (20:15-20:18) (pid 75))
|
||||
(e_lookup_local (20:15-20:18) (pid 75))
|
||||
(e_int (20:19-20:20)
|
||||
(int_var 143)
|
||||
(precision_var 142)
|
||||
|
@ -337,7 +337,7 @@ main! = |_| {
|
|||
(pid 147)
|
||||
(ident "result2"))
|
||||
(e_call (21:15-21:26)
|
||||
(e_lookup (21:15-21:23) (pid 91))
|
||||
(e_lookup_local (21:15-21:23) (pid 91))
|
||||
(e_int (21:24-21:25)
|
||||
(int_var 150)
|
||||
(precision_var 149)
|
||||
|
@ -349,7 +349,7 @@ main! = |_| {
|
|||
(pid 154)
|
||||
(ident "result3"))
|
||||
(e_call (22:15-22:25)
|
||||
(e_lookup (22:15-22:22) (pid 109))
|
||||
(e_lookup_local (22:15-22:22) (pid 109))
|
||||
(e_int (22:23-22:24)
|
||||
(int_var 157)
|
||||
(precision_var 156)
|
||||
|
@ -361,7 +361,7 @@ main! = |_| {
|
|||
(pid 161)
|
||||
(ident "result4"))
|
||||
(e_call (23:15-23:24)
|
||||
(e_lookup (23:15-23:21) (pid 124))
|
||||
(e_lookup_local (23:15-23:21) (pid 124))
|
||||
(e_int (23:22-23:23)
|
||||
(int_var 164)
|
||||
(precision_var 163)
|
||||
|
@ -370,14 +370,14 @@ main! = |_| {
|
|||
(bound "u8"))))
|
||||
(e_binop (24:5-25:2)
|
||||
"add"
|
||||
(e_lookup (24:5-24:12) (pid 140))
|
||||
(e_lookup_local (24:5-24:12) (pid 140))
|
||||
(e_binop (24:15-25:2)
|
||||
"add"
|
||||
(e_lookup (24:15-24:22) (pid 147))
|
||||
(e_lookup_local (24:15-24:22) (pid 147))
|
||||
(e_binop (24:25-25:2)
|
||||
"add"
|
||||
(e_lookup (24:25-24:32) (pid 154))
|
||||
(e_lookup (24:35-24:42) (pid 161))))))))))
|
||||
(e_lookup_local (24:25-24:32) (pid 154))
|
||||
(e_lookup_local (24:35-24:42) (pid 161))))))))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
|
@ -55,7 +55,7 @@ NO CHANGE
|
|||
(def_expr
|
||||
(e_string (3:7-3:22)
|
||||
(e_literal (3:8-3:14) "hello ")
|
||||
(e_lookup (3:16-3:20) (pid 72))
|
||||
(e_lookup_local (3:16-3:20) (pid 72))
|
||||
(e_literal (3:21-3:21) "")))))
|
||||
~~~
|
||||
# TYPES
|
||||
|
|
|
@ -10,9 +10,6 @@ module []
|
|||
import json.Json [foo, BAR]
|
||||
~~~
|
||||
# PROBLEMS
|
||||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: top-level import
|
||||
|
||||
**INVALID STATEMENT**
|
||||
The statement **expr** is not allowed at the top level.
|
||||
Only definitions, type annotations, and imports are allowed at the top level.
|
||||
|
@ -41,7 +38,12 @@ import json.Json[foo, BAR]
|
|||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can_ir "empty")
|
||||
(can_ir
|
||||
(s_import (3:1-3:17)
|
||||
"json.Json"
|
||||
""
|
||||
""
|
||||
(exposes)))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
34
src/snapshots/simple_external_lookup.md
generated
Normal file
34
src/snapshots/simple_external_lookup.md
generated
Normal file
|
@ -0,0 +1,34 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Simple external declaration lookup
|
||||
type=expr
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
List.map
|
||||
~~~
|
||||
# PROBLEMS
|
||||
**UNDEFINED VARIABLE**
|
||||
Nothing is named `map` in this scope.
|
||||
Is there an `import` or `exposing` missing up-top?
|
||||
|
||||
# TOKENS
|
||||
~~~zig
|
||||
UpperIdent(1:1-1:5),NoSpaceDotLowerIdent(1:5-1:9),EndOfFile(1:9-1:9),
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(ident (1:1-1:9) "List" ".map")
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(e_runtime_error (1:1-1:9) "ident_not_in_scope")
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(expr 73 (type "Error"))
|
||||
~~~
|
23
src/snapshots/simple_module_no_blanks.md
generated
23
src/snapshots/simple_module_no_blanks.md
generated
|
@ -11,13 +11,7 @@ hello! = Stdout.line!("Hello")
|
|||
world = "World"
|
||||
~~~
|
||||
# PROBLEMS
|
||||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: top-level import
|
||||
|
||||
**UNDEFINED VARIABLE**
|
||||
Nothing is named `line!` in this scope.
|
||||
Is there an `import` or `exposing` missing up-top?
|
||||
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwModule(1:1-1:7),OpenSquare(1:8-1:9),LowerIdent(1:9-1:15),Comma(1:15-1:16),LowerIdent(1:17-1:22),CloseSquare(1:22-1:23),Newline(1:1-1:1),
|
||||
|
@ -57,7 +51,13 @@ NO CHANGE
|
|||
(ident "hello!")))
|
||||
(def_expr
|
||||
(e_call (3:10-3:31)
|
||||
(e_runtime_error (3:10-3:22) "ident_not_in_scope")
|
||||
(e_lookup_external
|
||||
(external_decl (3:10-3:22)
|
||||
(qualified_name "pf.Stdout.line!")
|
||||
(module_name "pf.Stdout")
|
||||
(local_name "line!")
|
||||
(kind "value")
|
||||
(type_var 74)))
|
||||
(e_string (3:23-3:30) (e_literal (3:24-3:29) "Hello")))))
|
||||
(d_let
|
||||
(def_pattern
|
||||
|
@ -65,7 +65,12 @@ NO CHANGE
|
|||
(pid 80)
|
||||
(ident "world")))
|
||||
(def_expr
|
||||
(e_string (4:9-4:16) (e_literal (4:10-4:15) "World")))))
|
||||
(e_string (4:9-4:16) (e_literal (4:10-4:15) "World"))))
|
||||
(s_import (2:1-2:17)
|
||||
"pf.Stdout"
|
||||
""
|
||||
""
|
||||
(exposes)))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
212
src/snapshots/syntax_grab_bag.md
generated
212
src/snapshots/syntax_grab_bag.md
generated
|
@ -305,19 +305,12 @@ This type is referenced here:
|
|||
|
||||
|
||||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: top-level import
|
||||
This feature is not yet implemented: Exposed item 'line!' already imported from module 'pf.Stdout', cannot import again from module 'pf # Comment after qualifier
|
||||
.StdoutMultiline'
|
||||
|
||||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: top-level import
|
||||
|
||||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: top-level import
|
||||
|
||||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: top-level import
|
||||
|
||||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: top-level import
|
||||
This feature is not yet implemented: Exposed item 'write!' already imported from module 'pf.Stdout', cannot import again from module 'pf # Comment after qualifier
|
||||
.StdoutMultiline'
|
||||
|
||||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: canonicalize if_then_else expression
|
||||
|
@ -476,10 +469,6 @@ This feature is not yet implemented: canonicalize suffix_single_question express
|
|||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: canonicalize suffix_single_question expression
|
||||
|
||||
**UNDEFINED VARIABLE**
|
||||
Nothing is named `line!` in this scope.
|
||||
Is there an `import` or `exposing` missing up-top?
|
||||
|
||||
**UNDEFINED VARIABLE**
|
||||
Nothing is named `toStr` in this scope.
|
||||
Is there an `import` or `exposing` missing up-top?
|
||||
|
@ -1351,40 +1340,40 @@ NO CHANGE
|
|||
(d_let
|
||||
(def_pattern
|
||||
(p_assign (65:1-65:16)
|
||||
(pid 172)
|
||||
(pid 181)
|
||||
(ident "add_one_oneline")))
|
||||
(def_expr
|
||||
(e_lambda (65:19-67:8)
|
||||
(args
|
||||
(p_assign (65:20-65:23)
|
||||
(pid 173)
|
||||
(pid 182)
|
||||
(ident "num")))
|
||||
(e_runtime_error (1:1-1:1) "not_implemented"))))
|
||||
(d_let
|
||||
(def_pattern
|
||||
(p_assign (68:1-68:8)
|
||||
(pid 182)
|
||||
(pid 191)
|
||||
(ident "add_one")))
|
||||
(def_expr
|
||||
(e_lambda (68:11-78:2)
|
||||
(args
|
||||
(p_assign (68:12-68:15)
|
||||
(pid 183)
|
||||
(pid 192)
|
||||
(ident "num")))
|
||||
(e_block (68:17-78:2)
|
||||
(s_let (69:2-69:11)
|
||||
(p_assign (69:2-69:7)
|
||||
(pid 184)
|
||||
(pid 193)
|
||||
(ident "other"))
|
||||
(e_int (69:10-69:11)
|
||||
(int_var 186)
|
||||
(precision_var 185)
|
||||
(int_var 195)
|
||||
(precision_var 194)
|
||||
(literal "1")
|
||||
(value "TODO")
|
||||
(bound "u8")))
|
||||
(e_runtime_error (1:1-1:1) "not_implemented"))))
|
||||
(annotation (68:1-68:8)
|
||||
(signature 198)
|
||||
(signature 207)
|
||||
(declared_type
|
||||
(fn (67:11-67:21)
|
||||
(ty (67:11-67:14) "U64")
|
||||
|
@ -1393,46 +1382,46 @@ NO CHANGE
|
|||
(d_let
|
||||
(def_pattern
|
||||
(p_assign (80:1-80:11)
|
||||
(pid 201)
|
||||
(pid 210)
|
||||
(ident "match_time")))
|
||||
(def_expr
|
||||
(e_lambda (80:14-140:7)
|
||||
(args
|
||||
(p_assign (81:2-81:3)
|
||||
(pid 202)
|
||||
(pid 211)
|
||||
(ident "a"))
|
||||
(p_assign (82:2-82:3)
|
||||
(pid 203)
|
||||
(pid 212)
|
||||
(ident "b")))
|
||||
(e_runtime_error (1:1-1:1) "not_implemented"))))
|
||||
(d_let
|
||||
(def_pattern
|
||||
(p_assign (144:1-144:6)
|
||||
(pid 218)
|
||||
(pid 227)
|
||||
(ident "main!")))
|
||||
(def_expr
|
||||
(e_lambda (144:9-196:2)
|
||||
(args (p_underscore (144:10-144:11) (pid 219)))
|
||||
(args (p_underscore (144:10-144:11) (pid 228)))
|
||||
(e_block (144:13-196:2)
|
||||
(s_let (145:2-145:17)
|
||||
(p_assign (145:2-145:7)
|
||||
(pid 220)
|
||||
(pid 229)
|
||||
(ident "world"))
|
||||
(e_string (145:10-145:17) (e_literal (145:11-145:16) "World")))
|
||||
(s_var (146:2-147:8)
|
||||
(pid 227)
|
||||
(pid 236)
|
||||
(p_assign (146:2-147:8)
|
||||
(pid 227)
|
||||
(pid 236)
|
||||
(ident "number"))
|
||||
(e_int (146:15-146:18)
|
||||
(int_var 225)
|
||||
(precision_var 224)
|
||||
(int_var 234)
|
||||
(precision_var 233)
|
||||
(literal "123")
|
||||
(value "TODO")
|
||||
(bound "u8")))
|
||||
(s_let (148:2-148:12)
|
||||
(p_assign (148:2-148:5)
|
||||
(pid 231)
|
||||
(pid 240)
|
||||
(ident "tag"))
|
||||
(e_tag (148:8-148:12)
|
||||
(ext_var 0)
|
||||
|
@ -1441,7 +1430,7 @@ NO CHANGE
|
|||
(s_expr (154:2-155:12) (e_runtime_error (154:2-154:5) "not_implemented"))
|
||||
(s_expr (155:2-158:11)
|
||||
(e_call (155:2-157:3)
|
||||
(e_lookup (155:2-155:12) (pid 201))
|
||||
(e_lookup_local (155:2-155:12) (pid 210))
|
||||
(e_runtime_error (156:3-156:6) "not_implemented")))
|
||||
(s_expr (158:2-162:7)
|
||||
(e_call (158:2-161:3)
|
||||
|
@ -1449,106 +1438,106 @@ NO CHANGE
|
|||
(e_runtime_error (1:1-1:1) "not_implemented")))
|
||||
(s_let (164:2-164:31)
|
||||
(p_assign (164:2-164:18)
|
||||
(pid 253)
|
||||
(pid 262)
|
||||
(ident "tag_with_payload"))
|
||||
(e_call (164:21-164:31)
|
||||
(e_tag (164:21-164:23)
|
||||
(ext_var 0)
|
||||
(name "Ok")
|
||||
(args "TODO"))
|
||||
(e_lookup (164:24-164:30) (pid 227))))
|
||||
(e_lookup_local (164:24-164:30) (pid 236))))
|
||||
(s_let (165:2-165:34)
|
||||
(p_assign (165:2-165:14)
|
||||
(pid 259)
|
||||
(pid 268)
|
||||
(ident "interpolated"))
|
||||
(e_string (165:17-165:34)
|
||||
(e_literal (165:18-165:25) "Hello, ")
|
||||
(e_lookup (165:27-165:32) (pid 220))
|
||||
(e_lookup_local (165:27-165:32) (pid 229))
|
||||
(e_literal (165:33-165:33) "")))
|
||||
(s_let (166:2-173:3)
|
||||
(p_assign (166:2-166:6)
|
||||
(pid 265)
|
||||
(pid 274)
|
||||
(ident "list"))
|
||||
(e_list (166:9-173:3)
|
||||
(elem_var 276)
|
||||
(elem_var 285)
|
||||
(elems
|
||||
(e_call (167:3-170:4)
|
||||
(e_lookup (167:3-167:10) (pid 182))
|
||||
(e_lookup_local (167:3-167:10) (pid 191))
|
||||
(e_runtime_error (1:1-1:1) "not_implemented"))
|
||||
(e_int (171:3-171:6)
|
||||
(int_var 271)
|
||||
(precision_var 270)
|
||||
(int_var 280)
|
||||
(precision_var 279)
|
||||
(literal "456")
|
||||
(value "TODO")
|
||||
(bound "u8"))
|
||||
(e_int (172:3-172:6)
|
||||
(int_var 274)
|
||||
(precision_var 273)
|
||||
(int_var 283)
|
||||
(precision_var 282)
|
||||
(literal "789")
|
||||
(value "TODO")
|
||||
(bound "u8")))))
|
||||
(s_let (178:2-178:71)
|
||||
(p_assign (178:2-178:8)
|
||||
(pid 281)
|
||||
(pid 290)
|
||||
(ident "record"))
|
||||
(e_runtime_error (1:1-1:1) "not_implemented"))
|
||||
(s_let (179:2-179:68)
|
||||
(p_assign (179:2-179:7)
|
||||
(pid 285)
|
||||
(pid 294)
|
||||
(ident "tuple"))
|
||||
(e_tuple (179:10-179:68)
|
||||
(tuple_var "#312")
|
||||
(tuple_var "#321")
|
||||
(elems
|
||||
(e_int (179:11-179:14)
|
||||
(int_var 287)
|
||||
(precision_var 286)
|
||||
(int_var 296)
|
||||
(precision_var 295)
|
||||
(literal "123")
|
||||
(value "TODO")
|
||||
(bound "u8"))
|
||||
(e_string (179:16-179:23) (e_literal (179:17-179:22) "World"))
|
||||
(e_lookup (179:25-179:28) (pid 231))
|
||||
(e_lookup_local (179:25-179:28) (pid 240))
|
||||
(e_call (179:30-179:39)
|
||||
(e_tag (179:30-179:32)
|
||||
(ext_var 0)
|
||||
(name "Ok")
|
||||
(args "TODO"))
|
||||
(e_lookup (179:33-179:38) (pid 220)))
|
||||
(e_lookup_local (179:33-179:38) (pid 229)))
|
||||
(e_tuple (179:41-179:56)
|
||||
(tuple_var "#299")
|
||||
(tuple_var "#308")
|
||||
(elems
|
||||
(e_runtime_error (179:42-179:48) "ident_not_in_scope")
|
||||
(e_lookup (179:50-179:55) (pid 285))))
|
||||
(e_lookup_local (179:50-179:55) (pid 294))))
|
||||
(e_list (179:58-179:67)
|
||||
(elem_var 310)
|
||||
(elem_var 319)
|
||||
(elems
|
||||
(e_int (179:59-179:60)
|
||||
(int_var 302)
|
||||
(precision_var 301)
|
||||
(int_var 311)
|
||||
(precision_var 310)
|
||||
(literal "1")
|
||||
(value "TODO")
|
||||
(bound "u8"))
|
||||
(e_int (179:62-179:63)
|
||||
(int_var 305)
|
||||
(precision_var 304)
|
||||
(int_var 314)
|
||||
(precision_var 313)
|
||||
(literal "2")
|
||||
(value "TODO")
|
||||
(bound "u8"))
|
||||
(e_int (179:65-179:66)
|
||||
(int_var 308)
|
||||
(precision_var 307)
|
||||
(int_var 317)
|
||||
(precision_var 316)
|
||||
(literal "3")
|
||||
(value "TODO")
|
||||
(bound "u8")))))))
|
||||
(s_let (180:2-187:3)
|
||||
(p_assign (180:2-180:17)
|
||||
(pid 315)
|
||||
(pid 324)
|
||||
(ident "multiline_tuple"))
|
||||
(e_tuple (180:20-187:3)
|
||||
(tuple_var "#343")
|
||||
(tuple_var "#352")
|
||||
(elems
|
||||
(e_int (181:3-181:6)
|
||||
(int_var 317)
|
||||
(precision_var 316)
|
||||
(int_var 326)
|
||||
(precision_var 325)
|
||||
(literal "123")
|
||||
(value "TODO")
|
||||
(bound "u8"))
|
||||
|
@ -1559,41 +1548,41 @@ NO CHANGE
|
|||
(ext_var 0)
|
||||
(name "Ok")
|
||||
(args "TODO"))
|
||||
(e_lookup (184:6-184:11) (pid 220)))
|
||||
(e_lookup_local (184:6-184:11) (pid 229)))
|
||||
(e_tuple (185:3-185:18)
|
||||
(tuple_var "#330")
|
||||
(tuple_var "#339")
|
||||
(elems
|
||||
(e_runtime_error (185:4-185:10) "ident_not_in_scope")
|
||||
(e_lookup (185:12-185:17) (pid 285))))
|
||||
(e_lookup_local (185:12-185:17) (pid 294))))
|
||||
(e_list (186:3-186:12)
|
||||
(elem_var 341)
|
||||
(elem_var 350)
|
||||
(elems
|
||||
(e_int (186:4-186:5)
|
||||
(int_var 333)
|
||||
(precision_var 332)
|
||||
(int_var 342)
|
||||
(precision_var 341)
|
||||
(literal "1")
|
||||
(value "TODO")
|
||||
(bound "u8"))
|
||||
(e_int (186:7-186:8)
|
||||
(int_var 336)
|
||||
(precision_var 335)
|
||||
(int_var 345)
|
||||
(precision_var 344)
|
||||
(literal "2")
|
||||
(value "TODO")
|
||||
(bound "u8"))
|
||||
(e_int (186:10-186:11)
|
||||
(int_var 339)
|
||||
(precision_var 338)
|
||||
(int_var 348)
|
||||
(precision_var 347)
|
||||
(literal "3")
|
||||
(value "TODO")
|
||||
(bound "u8")))))))
|
||||
(s_let (188:2-189:23)
|
||||
(p_assign (188:2-188:15)
|
||||
(pid 346)
|
||||
(pid 355)
|
||||
(ident "bin_op_result"))
|
||||
(e_runtime_error (188:18-189:23) "not_implemented"))
|
||||
(s_let (189:2-190:8)
|
||||
(p_assign (189:2-189:23)
|
||||
(pid 410)
|
||||
(pid 419)
|
||||
(ident "static_dispatch_style"))
|
||||
(e_dot_access (189:26-190:8)
|
||||
(e_dot_access (189:26-189:110)
|
||||
|
@ -1604,15 +1593,21 @@ NO CHANGE
|
|||
"unknown"))
|
||||
(s_expr (190:2-191:8) (e_runtime_error (1:1-1:1) "not_implemented"))
|
||||
(e_call (191:2-195:3)
|
||||
(e_runtime_error (191:2-191:14) "ident_not_in_scope")
|
||||
(e_lookup_external
|
||||
(external_decl (191:2-191:14)
|
||||
(qualified_name "pf.Stdout.line!")
|
||||
(module_name "pf.Stdout")
|
||||
(local_name "line!")
|
||||
(kind "value")
|
||||
(type_var 429)))
|
||||
(e_string (192:3-194:18)
|
||||
(e_literal (192:4-192:14) "How about ")
|
||||
(e_call (193:4-193:21)
|
||||
(e_runtime_error (193:4-193:13) "ident_not_in_scope")
|
||||
(e_lookup (193:14-193:20) (pid 227)))
|
||||
(e_lookup_local (193:14-193:20) (pid 236)))
|
||||
(e_literal (194:4-194:17) " as a string?"))))))
|
||||
(annotation (144:1-144:6)
|
||||
(signature 442)
|
||||
(signature 451)
|
||||
(declared_type
|
||||
(fn (143:9-143:38)
|
||||
(apply (143:9-143:21)
|
||||
|
@ -1626,11 +1621,11 @@ NO CHANGE
|
|||
(d_let
|
||||
(def_pattern
|
||||
(p_assign (199:1-199:6)
|
||||
(pid 446)
|
||||
(pid 455)
|
||||
(ident "empty")))
|
||||
(def_expr (e_runtime_error (1:1-1:1) "not_implemented"))
|
||||
(annotation (199:1-199:6)
|
||||
(signature 450)
|
||||
(signature 459)
|
||||
(declared_type (record (198:9-198:11)))))
|
||||
(s_type_decl (22:1-23:6)
|
||||
(type_header (22:1-22:10)
|
||||
|
@ -1743,21 +1738,50 @@ NO CHANGE
|
|||
(apply (63:30-63:38)
|
||||
"Maybe"
|
||||
(ty_var (63:36-63:37) "a"))
|
||||
"false")))
|
||||
"false"))
|
||||
(s_import (4:1-4:42)
|
||||
"pf.Stdout"
|
||||
""
|
||||
""
|
||||
(exposes (exposed_item "line!") (exposed_item "write!")))
|
||||
(s_import (6:1-12:4)
|
||||
"pf # Comment after qualifier
|
||||
.StdoutMultiline"
|
||||
""
|
||||
""
|
||||
(exposes (exposed_item "line!") (exposed_item "write!")))
|
||||
(s_import (14:1-14:82)
|
||||
"pkg.Something"
|
||||
""
|
||||
""
|
||||
(exposes
|
||||
(exposed_item "func" "function")
|
||||
(exposed_item "Type" "ValueCategory")
|
||||
(exposed_item "Custom" "wildcard")))
|
||||
(s_import (16:1-16:27)
|
||||
"BadName"
|
||||
""
|
||||
""
|
||||
(exposes))
|
||||
(s_import (17:1-20:20)
|
||||
"BadNameMultiline"
|
||||
""
|
||||
""
|
||||
(exposes)))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred_types
|
||||
(defs
|
||||
(def "add_one_oneline" 178 (type "*"))
|
||||
(def "add_one" 200 (type "*"))
|
||||
(def "match_time" 209 (type "*"))
|
||||
(def "main!" 444 (type "*"))
|
||||
(def "empty" 452 (type "Error")))
|
||||
(def "add_one_oneline" 187 (type "*"))
|
||||
(def "add_one" 209 (type "*"))
|
||||
(def "match_time" 218 (type "*"))
|
||||
(def "main!" 453 (type "*"))
|
||||
(def "empty" 461 (type "Error")))
|
||||
(expressions
|
||||
(expr (65:19-67:8) 176 (type "*"))
|
||||
(expr (68:11-78:2) 193 (type "*"))
|
||||
(expr (80:14-140:7) 206 (type "*"))
|
||||
(expr (144:9-196:2) 438 (type "*"))
|
||||
(expr (199:9-199:11) 448 (type "Error"))))
|
||||
(expr (65:19-67:8) 185 (type "*"))
|
||||
(expr (68:11-78:2) 202 (type "*"))
|
||||
(expr (80:14-140:7) 215 (type "*"))
|
||||
(expr (144:9-196:2) 447 (type "*"))
|
||||
(expr (199:9-199:11) 457 (type "Error"))))
|
||||
~~~
|
6
src/snapshots/type_alias_parameterized.md
generated
6
src/snapshots/type_alias_parameterized.md
generated
|
@ -107,8 +107,8 @@ NO CHANGE
|
|||
(e_tuple (6:21-6:27)
|
||||
(tuple_var "#97")
|
||||
(elems
|
||||
(e_lookup (6:22-6:23) (pid 92))
|
||||
(e_lookup (6:25-6:26) (pid 91))))))
|
||||
(e_lookup_local (6:22-6:23) (pid 92))
|
||||
(e_lookup_local (6:25-6:26) (pid 91))))))
|
||||
(annotation (6:1-6:9)
|
||||
(signature 103)
|
||||
(declared_type
|
||||
|
@ -131,7 +131,7 @@ NO CHANGE
|
|||
(e_lambda (8:9-8:27)
|
||||
(args (p_underscore (8:10-8:11) (pid 107)))
|
||||
(e_call (8:13-8:27)
|
||||
(e_lookup (8:13-8:21) (pid 90))
|
||||
(e_lookup_local (8:13-8:21) (pid 90))
|
||||
(e_int (8:22-8:23)
|
||||
(int_var 110)
|
||||
(precision_var 109)
|
||||
|
|
2
src/snapshots/type_alias_simple.md
generated
2
src/snapshots/type_alias_simple.md
generated
|
@ -116,7 +116,7 @@ NO CHANGE
|
|||
(e_lambda (8:9-8:25)
|
||||
(args (p_underscore (8:10-8:11) (pid 91)))
|
||||
(e_call (8:13-8:25)
|
||||
(e_lookup (8:13-8:20) (pid 78))
|
||||
(e_lookup_local (8:13-8:20) (pid 78))
|
||||
(e_int (8:21-8:24)
|
||||
(int_var 94)
|
||||
(precision_var 93)
|
||||
|
|
4
src/snapshots/type_anno_connection.md
generated
4
src/snapshots/type_anno_connection.md
generated
|
@ -73,7 +73,7 @@ NO CHANGE
|
|||
(ident "x")))
|
||||
(e_binop (4:15-6:10)
|
||||
"add"
|
||||
(e_lookup (4:15-4:16) (pid 76))
|
||||
(e_lookup_local (4:15-4:16) (pid 76))
|
||||
(e_int (4:19-4:20)
|
||||
(int_var 79)
|
||||
(precision_var 78)
|
||||
|
@ -94,7 +94,7 @@ NO CHANGE
|
|||
(ident "my_number")))
|
||||
(def_expr
|
||||
(e_call (7:13-7:24)
|
||||
(e_lookup (7:13-7:20) (pid 75))
|
||||
(e_lookup_local (7:13-7:20) (pid 75))
|
||||
(e_int (7:21-7:23)
|
||||
(int_var 93)
|
||||
(precision_var 92)
|
||||
|
|
22
src/snapshots/type_annotation_basic.md
generated
22
src/snapshots/type_annotation_basic.md
generated
|
@ -201,7 +201,7 @@ main! = |_| {
|
|||
(p_assign (5:13-5:14)
|
||||
(pid 78)
|
||||
(ident "x")))
|
||||
(e_lookup (5:16-5:17) (pid 78))))
|
||||
(e_lookup_local (5:16-5:17) (pid 78))))
|
||||
(annotation (5:1-5:9)
|
||||
(signature 85)
|
||||
(declared_type
|
||||
|
@ -226,8 +226,8 @@ main! = |_| {
|
|||
(e_tuple (9:27-9:42)
|
||||
(tuple_var "#103")
|
||||
(elems
|
||||
(e_lookup (9:28-9:33) (pid 99))
|
||||
(e_lookup (9:35-9:41) (pid 100))))))
|
||||
(e_lookup_local (9:28-9:33) (pid 99))
|
||||
(e_lookup_local (9:35-9:41) (pid 100))))))
|
||||
(annotation (9:1-9:8)
|
||||
(signature 111)
|
||||
(declared_type
|
||||
|
@ -251,7 +251,7 @@ main! = |_| {
|
|||
(ident "n")))
|
||||
(e_binop (13:14-15:6)
|
||||
"add"
|
||||
(e_lookup (13:14-13:15) (pid 118))
|
||||
(e_lookup_local (13:14-13:15) (pid 118))
|
||||
(e_int (13:18-13:19)
|
||||
(int_var 121)
|
||||
(precision_var 120)
|
||||
|
@ -279,7 +279,7 @@ main! = |_| {
|
|||
(pid 133)
|
||||
(ident "num"))
|
||||
(e_call (17:11-17:23)
|
||||
(e_lookup (17:11-17:19) (pid 77))
|
||||
(e_lookup_local (17:11-17:19) (pid 77))
|
||||
(e_int (17:20-17:22)
|
||||
(int_var 136)
|
||||
(precision_var 135)
|
||||
|
@ -291,29 +291,29 @@ main! = |_| {
|
|||
(pid 140)
|
||||
(ident "text"))
|
||||
(e_call (18:12-18:29)
|
||||
(e_lookup (18:12-18:20) (pid 77))
|
||||
(e_lookup_local (18:12-18:20) (pid 77))
|
||||
(e_string (18:21-18:28) (e_literal (18:22-18:27) "hello"))))
|
||||
(s_let (21:5-21:30)
|
||||
(p_assign (21:5-21:9)
|
||||
(pid 146)
|
||||
(ident "pair"))
|
||||
(e_call (21:12-21:30)
|
||||
(e_lookup (21:12-21:19) (pid 98))
|
||||
(e_lookup (21:20-21:23) (pid 133))
|
||||
(e_lookup (21:25-21:29) (pid 140))))
|
||||
(e_lookup_local (21:12-21:19) (pid 98))
|
||||
(e_lookup_local (21:20-21:23) (pid 133))
|
||||
(e_lookup_local (21:25-21:29) (pid 140))))
|
||||
(s_let (24:5-24:23)
|
||||
(p_assign (24:5-24:11)
|
||||
(pid 152)
|
||||
(ident "result"))
|
||||
(e_call (24:14-24:23)
|
||||
(e_lookup (24:14-24:20) (pid 117))
|
||||
(e_lookup_local (24:14-24:20) (pid 117))
|
||||
(e_int (24:21-24:22)
|
||||
(int_var 155)
|
||||
(precision_var 154)
|
||||
(literal "5")
|
||||
(value "TODO")
|
||||
(bound "u8"))))
|
||||
(e_lookup (26:5-26:11) (pid 152)))))))
|
||||
(e_lookup_local (26:5-26:11) (pid 152)))))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
2
src/snapshots/type_app_complex_nested.md
generated
2
src/snapshots/type_app_complex_nested.md
generated
|
@ -338,7 +338,7 @@ main! = |_| processComplex(Ok([Some(42), None]))
|
|||
(e_lambda (17:9-17:49)
|
||||
(args (p_underscore (17:10-17:11) (pid 140)))
|
||||
(e_call (17:13-17:49)
|
||||
(e_lookup (17:13-17:27) (pid 98))
|
||||
(e_lookup_local (17:13-17:27) (pid 98))
|
||||
(e_call (17:28-17:48)
|
||||
(e_tag (17:28-17:30)
|
||||
(ext_var 0)
|
||||
|
|
2
src/snapshots/type_app_multiple_args.md
generated
2
src/snapshots/type_app_multiple_args.md
generated
|
@ -110,7 +110,7 @@ NO CHANGE
|
|||
(e_lambda (6:9-6:55)
|
||||
(args (p_underscore (6:10-6:11) (pid 90)))
|
||||
(e_call (6:13-6:55)
|
||||
(e_lookup (6:13-6:24) (pid 78))
|
||||
(e_lookup_local (6:13-6:24) (pid 78))
|
||||
(e_dot_access (6:25-6:55)
|
||||
(e_call (6:25-6:37) (e_runtime_error (6:25-6:35) "ident_not_in_scope"))
|
||||
"insert"
|
||||
|
|
2
src/snapshots/type_app_nested.md
generated
2
src/snapshots/type_app_nested.md
generated
|
@ -123,7 +123,7 @@ main! = |_| processNested([])
|
|||
(e_lambda (6:9-6:30)
|
||||
(args (p_underscore (6:10-6:11) (pid 96)))
|
||||
(e_call (6:13-6:30)
|
||||
(e_lookup (6:13-6:26) (pid 80))
|
||||
(e_lookup_local (6:13-6:26) (pid 80))
|
||||
(e_list (6:27-6:29) (elem_var 98) (elems)))))))
|
||||
~~~
|
||||
# TYPES
|
||||
|
|
4
src/snapshots/type_app_single_arg.md
generated
4
src/snapshots/type_app_single_arg.md
generated
|
@ -87,7 +87,7 @@ main! = |_| processList(["one", "two"])
|
|||
(pid 77)
|
||||
(ident "list")))
|
||||
(e_dot_access (4:22-6:6)
|
||||
(e_lookup (4:22-4:26) (pid 77))
|
||||
(e_lookup_local (4:22-4:26) (pid 77))
|
||||
"len")))
|
||||
(annotation (4:1-4:12)
|
||||
(signature 84)
|
||||
|
@ -107,7 +107,7 @@ main! = |_| processList(["one", "two"])
|
|||
(e_lambda (6:9-6:39)
|
||||
(args (p_underscore (6:10-6:11) (pid 88)))
|
||||
(e_call (6:13-6:39)
|
||||
(e_lookup (6:13-6:24) (pid 76))
|
||||
(e_lookup_local (6:13-6:24) (pid 76))
|
||||
(e_list (6:25-6:38)
|
||||
(elem_var 94)
|
||||
(elems
|
||||
|
|
6
src/snapshots/type_app_with_vars.md
generated
6
src/snapshots/type_app_with_vars.md
generated
|
@ -101,9 +101,9 @@ main! = |_| mapList([1, 2, 3, 4, 5])
|
|||
(pid 87)
|
||||
(ident "fn")))
|
||||
(e_dot_access (4:22-6:6)
|
||||
(e_lookup (4:22-4:26) (pid 86))
|
||||
(e_lookup_local (4:22-4:26) (pid 86))
|
||||
"map"
|
||||
(e_lookup (4:31-4:33) (pid 87)))))
|
||||
(e_lookup_local (4:31-4:33) (pid 87)))))
|
||||
(annotation (4:1-4:8)
|
||||
(signature 100)
|
||||
(declared_type
|
||||
|
@ -129,7 +129,7 @@ main! = |_| mapList([1, 2, 3, 4, 5])
|
|||
(e_lambda (6:9-6:33)
|
||||
(args (p_underscore (6:10-6:11) (pid 104)))
|
||||
(e_call (6:13-6:33)
|
||||
(e_lookup (6:13-6:20) (pid 85))
|
||||
(e_lookup_local (6:13-6:20) (pid 85))
|
||||
(e_list (6:21-6:32)
|
||||
(elem_var 121)
|
||||
(elems
|
||||
|
|
4
src/snapshots/type_application_basic.md
generated
4
src/snapshots/type_application_basic.md
generated
|
@ -88,7 +88,7 @@ main! = |_| processList(["one", "two", "three"])
|
|||
(pid 77)
|
||||
(ident "list")))
|
||||
(e_dot_access (4:22-6:6)
|
||||
(e_lookup (4:22-4:26) (pid 77))
|
||||
(e_lookup_local (4:22-4:26) (pid 77))
|
||||
"len")))
|
||||
(annotation (4:1-4:12)
|
||||
(signature 84)
|
||||
|
@ -108,7 +108,7 @@ main! = |_| processList(["one", "two", "three"])
|
|||
(e_lambda (6:9-6:47)
|
||||
(args (p_underscore (6:10-6:11) (pid 88)))
|
||||
(e_call (6:13-6:47)
|
||||
(e_lookup (6:13-6:24) (pid 76))
|
||||
(e_lookup_local (6:13-6:24) (pid 76))
|
||||
(e_list (6:25-6:46)
|
||||
(elem_var 96)
|
||||
(elems
|
||||
|
|
4
src/snapshots/type_function_basic.md
generated
4
src/snapshots/type_function_basic.md
generated
|
@ -108,8 +108,8 @@ main! = |_| {}
|
|||
(pid 82)
|
||||
(ident "x")))
|
||||
(e_call (4:17-4:22)
|
||||
(e_lookup (4:17-4:19) (pid 81))
|
||||
(e_lookup (4:20-4:21) (pid 82)))))
|
||||
(e_lookup_local (4:17-4:19) (pid 81))
|
||||
(e_lookup_local (4:20-4:21) (pid 82)))))
|
||||
(annotation (4:1-4:6)
|
||||
(signature 92)
|
||||
(declared_type
|
||||
|
|
4
src/snapshots/type_function_effectful.md
generated
4
src/snapshots/type_function_effectful.md
generated
|
@ -127,8 +127,8 @@ main! = |_| {}
|
|||
(pid 84)
|
||||
(ident "x")))
|
||||
(e_call (4:23-4:29)
|
||||
(e_lookup (4:23-4:26) (pid 83))
|
||||
(e_lookup (4:27-4:28) (pid 84)))))
|
||||
(e_lookup_local (4:23-4:26) (pid 83))
|
||||
(e_lookup_local (4:27-4:28) (pid 84)))))
|
||||
(annotation (4:1-4:11)
|
||||
(signature 94)
|
||||
(declared_type
|
||||
|
|
6
src/snapshots/type_function_multi_arg.md
generated
6
src/snapshots/type_function_multi_arg.md
generated
|
@ -122,9 +122,9 @@ main! = |_| {}
|
|||
(pid 85)
|
||||
(ident "y")))
|
||||
(e_call (4:22-4:30)
|
||||
(e_lookup (4:22-4:24) (pid 83))
|
||||
(e_lookup (4:25-4:26) (pid 84))
|
||||
(e_lookup (4:28-4:29) (pid 85)))))))
|
||||
(e_lookup_local (4:22-4:24) (pid 83))
|
||||
(e_lookup_local (4:25-4:26) (pid 84))
|
||||
(e_lookup_local (4:28-4:29) (pid 85)))))))
|
||||
(annotation (4:1-4:6)
|
||||
(signature 100)
|
||||
(declared_type
|
||||
|
|
4
src/snapshots/type_function_simple.md
generated
4
src/snapshots/type_function_simple.md
generated
|
@ -108,8 +108,8 @@ main! = |_| {}
|
|||
(pid 82)
|
||||
(ident "x")))
|
||||
(e_call (4:17-4:22)
|
||||
(e_lookup (4:17-4:19) (pid 81))
|
||||
(e_lookup (4:20-4:21) (pid 82)))))
|
||||
(e_lookup_local (4:17-4:19) (pid 81))
|
||||
(e_lookup_local (4:20-4:21) (pid 82)))))
|
||||
(annotation (4:1-4:6)
|
||||
(signature 92)
|
||||
(declared_type
|
||||
|
|
6
src/snapshots/type_higher_order_multiple_vars.md
generated
6
src/snapshots/type_higher_order_multiple_vars.md
generated
|
@ -149,10 +149,10 @@ main! = |_| {}
|
|||
(pid 85)
|
||||
(ident "x")))
|
||||
(e_call (4:22-4:29)
|
||||
(e_lookup (4:22-4:23) (pid 83))
|
||||
(e_lookup_local (4:22-4:23) (pid 83))
|
||||
(e_call (4:24-4:28)
|
||||
(e_lookup (4:24-4:25) (pid 84))
|
||||
(e_lookup (4:26-4:27) (pid 85)))))))
|
||||
(e_lookup_local (4:24-4:25) (pid 84))
|
||||
(e_lookup_local (4:26-4:27) (pid 85)))))))
|
||||
(annotation (4:1-4:8)
|
||||
(signature 98)
|
||||
(declared_type
|
||||
|
|
8
src/snapshots/type_multiple_aliases.md
generated
8
src/snapshots/type_multiple_aliases.md
generated
|
@ -219,7 +219,7 @@ main! = |_| {
|
|||
(pid 117)
|
||||
(ident "user")))
|
||||
(e_dot_access (12:22-14:6)
|
||||
(e_lookup (12:22-12:26) (pid 117))
|
||||
(e_lookup_local (12:22-12:26) (pid 117))
|
||||
"name")))
|
||||
(annotation (12:1-12:12)
|
||||
(signature 124)
|
||||
|
@ -242,7 +242,7 @@ main! = |_| {
|
|||
(pid 129)
|
||||
(ident "user"))
|
||||
(e_call (15:12-15:40)
|
||||
(e_lookup (15:12-15:22) (pid 95))
|
||||
(e_lookup_local (15:12-15:22) (pid 95))
|
||||
(e_int (15:23-15:26)
|
||||
(int_var 132)
|
||||
(precision_var 131)
|
||||
|
@ -257,8 +257,8 @@ main! = |_| {
|
|||
(value "TODO")
|
||||
(bound "u8"))))
|
||||
(e_call (16:5-16:22)
|
||||
(e_lookup (16:5-16:16) (pid 116))
|
||||
(e_lookup (16:17-16:21) (pid 129)))))))
|
||||
(e_lookup_local (16:5-16:16) (pid 116))
|
||||
(e_lookup_local (16:17-16:21) (pid 129)))))))
|
||||
(s_type_decl (3:1-4:9)
|
||||
(type_header (3:1-3:7) "UserId")
|
||||
(ty (3:10-3:13) "U64"))
|
||||
|
|
2
src/snapshots/type_record_basic.md
generated
2
src/snapshots/type_record_basic.md
generated
|
@ -104,7 +104,7 @@ main! = |_| getName({ name: "luke", age: 21 })
|
|||
(e_lambda (6:9-6:44)
|
||||
(args (p_underscore (6:10-6:11) (pid 91)))
|
||||
(e_call (6:13-6:44)
|
||||
(e_lookup (6:13-6:20) (pid 79))
|
||||
(e_lookup_local (6:13-6:20) (pid 79))
|
||||
(e_runtime_error (1:1-1:1) "not_implemented"))))))
|
||||
~~~
|
||||
# TYPES
|
||||
|
|
2
src/snapshots/type_record_simple.md
generated
2
src/snapshots/type_record_simple.md
generated
|
@ -84,7 +84,7 @@ main! = |_| {}
|
|||
(pid 80)
|
||||
(ident "person")))
|
||||
(e_dot_access (4:20-6:6)
|
||||
(e_lookup (4:20-4:26) (pid 80))
|
||||
(e_lookup_local (4:20-4:26) (pid 80))
|
||||
"name")))
|
||||
(annotation (4:1-4:8)
|
||||
(signature 87)
|
||||
|
|
2
src/snapshots/type_record_with_vars.md
generated
2
src/snapshots/type_record_with_vars.md
generated
|
@ -100,7 +100,7 @@ main! = |_| {}
|
|||
(pid 82)
|
||||
(ident "record")))
|
||||
(e_dot_access (4:21-6:6)
|
||||
(e_lookup (4:21-4:27) (pid 82))
|
||||
(e_lookup_local (4:21-4:27) (pid 82))
|
||||
"field")))
|
||||
(annotation (4:1-4:9)
|
||||
(signature 90)
|
||||
|
|
4
src/snapshots/type_same_var_multiple_uses.md
generated
4
src/snapshots/type_same_var_multiple_uses.md
generated
|
@ -79,8 +79,8 @@ NO CHANGE
|
|||
(e_tuple (4:12-4:18)
|
||||
(tuple_var "#84")
|
||||
(elems
|
||||
(e_lookup (4:13-4:14) (pid 81))
|
||||
(e_lookup (4:16-4:17) (pid 81))))))
|
||||
(e_lookup_local (4:13-4:14) (pid 81))
|
||||
(e_lookup_local (4:16-4:17) (pid 81))))))
|
||||
(annotation (4:1-4:5)
|
||||
(signature 91)
|
||||
(declared_type
|
||||
|
|
2
src/snapshots/type_simple_type_var.md
generated
2
src/snapshots/type_simple_type_var.md
generated
|
@ -72,7 +72,7 @@ NO CHANGE
|
|||
(p_assign (4:13-4:14)
|
||||
(pid 78)
|
||||
(ident "x")))
|
||||
(e_lookup (4:16-4:17) (pid 78))))
|
||||
(e_lookup_local (4:16-4:17) (pid 78))))
|
||||
(annotation (4:1-4:9)
|
||||
(signature 85)
|
||||
(declared_type
|
||||
|
|
4
src/snapshots/type_two_variables.md
generated
4
src/snapshots/type_two_variables.md
generated
|
@ -91,8 +91,8 @@ NO CHANGE
|
|||
(e_tuple (4:17-4:23)
|
||||
(tuple_var "#90")
|
||||
(elems
|
||||
(e_lookup (4:18-4:19) (pid 85))
|
||||
(e_lookup (4:21-4:22) (pid 84))))))
|
||||
(e_lookup_local (4:18-4:19) (pid 85))
|
||||
(e_lookup_local (4:21-4:22) (pid 84))))))
|
||||
(annotation (4:1-4:5)
|
||||
(signature 96)
|
||||
(declared_type
|
||||
|
|
2
src/snapshots/type_var_basic.md
generated
2
src/snapshots/type_var_basic.md
generated
|
@ -74,7 +74,7 @@ NO CHANGE
|
|||
(p_assign (5:13-5:14)
|
||||
(pid 78)
|
||||
(ident "a")))
|
||||
(e_lookup (5:16-5:17) (pid 78))))
|
||||
(e_lookup_local (5:16-5:17) (pid 78))))
|
||||
(annotation (5:1-5:9)
|
||||
(signature 85)
|
||||
(declared_type
|
||||
|
|
2
src/snapshots/type_var_multiple.md
generated
2
src/snapshots/type_var_multiple.md
generated
|
@ -139,7 +139,7 @@ main! = |_| {}
|
|||
(e_runtime_error (6:6-6:11) "ident_not_in_scope")
|
||||
(e_runtime_error (6:13-6:19) "ident_not_in_scope"))))
|
||||
(s_expr (6:23-7:6)
|
||||
(e_lookup (6:23-6:27) (pid 84)))
|
||||
(e_lookup_local (6:23-6:27) (pid 84)))
|
||||
(e_tuple (7:5-7:20)
|
||||
(tuple_var "#98")
|
||||
(elems
|
||||
|
|
6
src/snapshots/type_var_namespace.md
generated
6
src/snapshots/type_var_namespace.md
generated
|
@ -176,12 +176,12 @@ main! = |_| {}
|
|||
(ident "result"))
|
||||
(e_call (11:14-11:30)
|
||||
(e_runtime_error (11:14-11:24) "ident_not_in_scope")
|
||||
(e_lookup (11:25-11:29) (pid 79))))
|
||||
(e_lookup_local (11:25-11:29) (pid 79))))
|
||||
(s_expr (11:34-13:11)
|
||||
(e_call (11:34-11:58)
|
||||
(e_runtime_error (11:34-11:52) "ident_not_in_scope")
|
||||
(e_lookup (11:53-11:57) (pid 80))))
|
||||
(e_lookup (13:5-13:11) (pid 89)))))
|
||||
(e_lookup_local (11:53-11:57) (pid 80))))
|
||||
(e_lookup_local (13:5-13:11) (pid 89)))))
|
||||
(annotation (5:1-5:8)
|
||||
(signature 107)
|
||||
(declared_type
|
||||
|
|
4
src/snapshots/type_var_nested.md
generated
4
src/snapshots/type_var_nested.md
generated
|
@ -198,7 +198,7 @@ main! = |_| {}
|
|||
(e_block (5:33-9:2)
|
||||
(s_expr (6:5-6:16) (e_runtime_error (6:5-6:9) "ident_not_in_scope"))
|
||||
(s_expr (6:10-6:19)
|
||||
(e_lookup (6:10-6:16) (pid 90)))
|
||||
(e_lookup_local (6:10-6:16) (pid 90)))
|
||||
(s_expr (6:17-7:11) (e_runtime_error (6:17-6:19) "ident_not_in_scope"))
|
||||
(s_expr (7:9-8:12) (e_runtime_error (1:1-1:1) "not_implemented"))
|
||||
(e_runtime_error (1:1-1:1) "not_implemented"))))
|
||||
|
@ -234,7 +234,7 @@ main! = |_| {}
|
|||
(e_block (13:23-15:2)
|
||||
(e_call (14:5-14:23)
|
||||
(e_runtime_error (14:5-14:17) "ident_not_in_scope")
|
||||
(e_lookup (14:18-14:22) (pid 128))))))
|
||||
(e_lookup_local (14:18-14:22) (pid 128))))))
|
||||
(annotation (13:1-13:13)
|
||||
(signature 138)
|
||||
(declared_type
|
||||
|
|
4
src/snapshots/unused_vars_block.md
generated
4
src/snapshots/unused_vars_block.md
generated
|
@ -184,14 +184,14 @@ main! = |_| {
|
|||
(ident "result"))
|
||||
(e_binop (17:14-18:11)
|
||||
"add"
|
||||
(e_lookup (17:14-17:22) (pid 79))
|
||||
(e_lookup_local (17:14-17:22) (pid 79))
|
||||
(e_int (17:25-17:27)
|
||||
(int_var 96)
|
||||
(precision_var 95)
|
||||
(literal "10")
|
||||
(value "TODO")
|
||||
(bound "u8"))))
|
||||
(e_lookup (18:5-18:11) (pid 93)))))))
|
||||
(e_lookup_local (18:5-18:11) (pid 93)))))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
20
src/snapshots/unused_vars_simple.md
generated
20
src/snapshots/unused_vars_simple.md
generated
|
@ -202,7 +202,7 @@ main! = |_| {
|
|||
(p_assign (7:20-7:26)
|
||||
(pid 81)
|
||||
(ident "_value")))
|
||||
(e_lookup (7:28-7:34) (pid 81)))))
|
||||
(e_lookup_local (7:28-7:34) (pid 81)))))
|
||||
(d_let
|
||||
(def_pattern
|
||||
(p_assign (10:1-10:18)
|
||||
|
@ -233,7 +233,7 @@ main! = |_| {
|
|||
(ident "number")))
|
||||
(e_binop (13:25-15:6)
|
||||
"add"
|
||||
(e_lookup (13:25-13:31) (pid 94))
|
||||
(e_lookup_local (13:25-13:31) (pid 94))
|
||||
(e_int (13:34-13:35)
|
||||
(int_var 97)
|
||||
(precision_var 96)
|
||||
|
@ -254,7 +254,7 @@ main! = |_| {
|
|||
(pid 104)
|
||||
(ident "a"))
|
||||
(e_call (16:9-16:26)
|
||||
(e_lookup (16:9-16:23) (pid 72))
|
||||
(e_lookup_local (16:9-16:23) (pid 72))
|
||||
(e_int (16:24-16:25)
|
||||
(int_var 107)
|
||||
(precision_var 106)
|
||||
|
@ -266,7 +266,7 @@ main! = |_| {
|
|||
(pid 111)
|
||||
(ident "b"))
|
||||
(e_call (17:9-17:28)
|
||||
(e_lookup (17:9-17:24) (pid 80))
|
||||
(e_lookup_local (17:9-17:24) (pid 80))
|
||||
(e_int (17:25-17:27)
|
||||
(int_var 114)
|
||||
(precision_var 113)
|
||||
|
@ -278,7 +278,7 @@ main! = |_| {
|
|||
(pid 118)
|
||||
(ident "c"))
|
||||
(e_call (18:9-18:30)
|
||||
(e_lookup (18:9-18:26) (pid 86))
|
||||
(e_lookup_local (18:9-18:26) (pid 86))
|
||||
(e_int (18:27-18:29)
|
||||
(int_var 121)
|
||||
(precision_var 120)
|
||||
|
@ -290,7 +290,7 @@ main! = |_| {
|
|||
(pid 125)
|
||||
(ident "d"))
|
||||
(e_call (19:9-19:25)
|
||||
(e_lookup (19:9-19:21) (pid 93))
|
||||
(e_lookup_local (19:9-19:21) (pid 93))
|
||||
(e_int (19:22-19:24)
|
||||
(int_var 128)
|
||||
(precision_var 127)
|
||||
|
@ -299,14 +299,14 @@ main! = |_| {
|
|||
(bound "u8"))))
|
||||
(e_binop (20:5-21:2)
|
||||
"add"
|
||||
(e_lookup (20:5-20:6) (pid 104))
|
||||
(e_lookup_local (20:5-20:6) (pid 104))
|
||||
(e_binop (20:9-21:2)
|
||||
"add"
|
||||
(e_lookup (20:9-20:10) (pid 111))
|
||||
(e_lookup_local (20:9-20:10) (pid 111))
|
||||
(e_binop (20:13-21:2)
|
||||
"add"
|
||||
(e_lookup (20:13-20:14) (pid 118))
|
||||
(e_lookup (20:17-20:18) (pid 125))))))))))
|
||||
(e_lookup_local (20:13-20:14) (pid 118))
|
||||
(e_lookup_local (20:17-20:18) (pid 125))))))))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
11
src/snapshots/where_clauses_10.md
generated
11
src/snapshots/where_clauses_10.md
generated
|
@ -16,9 +16,7 @@ decodeThings # After member name
|
|||
a.Decode,
|
||||
~~~
|
||||
# PROBLEMS
|
||||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: top-level import
|
||||
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwModule(1:1-1:7),OpenSquare(1:8-1:9),LowerIdent(1:9-1:15),CloseSquare(1:15-1:16),Newline(1:1-1:1),
|
||||
|
@ -58,7 +56,12 @@ NO CHANGE
|
|||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can_ir "empty")
|
||||
(can_ir
|
||||
(s_import (3:1-3:32)
|
||||
"Decode"
|
||||
""
|
||||
""
|
||||
(exposes (exposed_item "Decode"))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
11
src/snapshots/where_clauses_4.md
generated
11
src/snapshots/where_clauses_4.md
generated
|
@ -13,9 +13,7 @@ decodeThings : List(List(U8)) -> List(a)
|
|||
where a.Decode
|
||||
~~~
|
||||
# PROBLEMS
|
||||
**NOT IMPLEMENTED**
|
||||
This feature is not yet implemented: top-level import
|
||||
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
KwModule(1:1-1:7),OpenSquare(1:8-1:9),LowerIdent(1:9-1:15),CloseSquare(1:15-1:16),Newline(1:1-1:1),
|
||||
|
@ -52,7 +50,12 @@ NO CHANGE
|
|||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can_ir "empty")
|
||||
(can_ir
|
||||
(s_import (3:1-3:32)
|
||||
"Decode"
|
||||
""
|
||||
""
|
||||
(exposes (exposed_item "Decode"))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue