Skip to content

Commit 0a1d8a5

Browse files
committed
compiler: unify expression pipeline
The entire expression pipeline now flows through a single path: buildExpr → GoExpr nodes → printer.
1 parent 0410900 commit 0a1d8a5

8 files changed

Lines changed: 149 additions & 724 deletions

File tree

ast/preprocess.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1527,7 +1527,6 @@ func expandInlineFnLine(line string) string {
15271527
if paramEnd < 0 {
15281528
// No matching ) — leave unchanged
15291529
buf.WriteString(line[fnIdx:])
1530-
pos = len(line)
15311530
break
15321531
}
15331532

cmd/cmd.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,7 @@ func Execute(version string) {
202202
}
203203

204204
// Inject installed tools as top-level commands so they appear in help.
205-
for _, tc := range installedToolCommands() {
206-
cmd.Commands = append(cmd.Commands, tc)
207-
}
205+
cmd.Commands = append(cmd.Commands, installedToolCommands()...)
208206

209207
if err := cmd.Run(context.Background(), os.Args); err != nil {
210208
fmt.Fprintln(os.Stderr, formatError(err.Error()))
@@ -428,7 +426,7 @@ func modTidyAction(ctx context.Context, cmd *cli.Command) error {
428426
continue
429427
}
430428
if existing, ok := moduleVersions[mod]; ok && existing.version != ver {
431-
return fmt.Errorf("version conflict for %s:\n %s requires %s\n %s requires %s\nAlign on a single version, then re-run 'rugo mod tidy'.",
429+
return fmt.Errorf("version conflict for %s:\n %s requires %s\n %s requires %s\nAlign on a single version, then re-run 'rugo mod tidy'",
432430
mod, existing.file, existing.version, filepath.Base(f), ver)
433431
}
434432
moduleVersions[mod] = modSource{version: ver, file: filepath.Base(f)}

compiler/codegen.go

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ type codeGen struct {
5050
lambdaDepth int // nesting depth of lambda bodies (>0 means inside fn)
5151
lambdaScopeBase []int // scope index at each lambda entry (stack)
5252
lambdaOuterFunc []*ast.FuncDef // enclosing function at each lambda entry (stack)
53-
indent int // current indent level for nested expression rendering
5453
sandbox *SandboxConfig // Landlock sandbox config (nil = no sandbox)
5554
}
5655

@@ -429,54 +428,56 @@ func (g *codeGen) ensureFloat(s string, t RugoType) string {
429428
return s
430429
}
431430

432-
// boxedArgs returns comma-joined args, boxing typed values for runtime helpers.
433-
func (g *codeGen) boxedArgs(args []string, exprs []ast.Expr) string {
434-
result := make([]string, len(args))
431+
// boxedExprs wraps typed GoExpr args in GoCastExpr for runtime helpers.
432+
func (g *codeGen) boxedExprs(args []GoExpr, exprs []ast.Expr) []GoExpr {
433+
result := make([]GoExpr, len(args))
435434
for i, a := range args {
436-
result[i] = g.boxed(a, g.exprType(exprs[i]))
435+
if g.exprType(exprs[i]).IsTyped() {
436+
result[i] = GoCastExpr{Type: "interface{}", Value: a}
437+
} else {
438+
result[i] = a
439+
}
437440
}
438-
return strings.Join(result, ", ")
441+
return result
439442
}
440443

441-
// typedCallArgs generates the argument list for a user-defined function call,
444+
// typedCallExprs generates GoExpr arguments for a user-defined function call,
442445
// converting typed args to match the function's typed param signature.
443-
func (g *codeGen) typedCallArgs(funcName string, args []string, argExprs []ast.Expr) string {
446+
func (g *codeGen) typedCallExprs(funcName string, args []GoExpr, argExprs []ast.Expr) []GoExpr {
444447
if g.typeInfo == nil {
445-
return strings.Join(args, ", ")
448+
return args
446449
}
447450
fti, ok := g.typeInfo.FuncTypes[funcName]
448451
if !ok {
449-
return strings.Join(args, ", ")
452+
return args
450453
}
451454

452-
result := make([]string, len(args))
455+
result := make([]GoExpr, len(args))
453456
for i, a := range args {
454457
argType := g.exprType(argExprs[i])
455458
if i < len(fti.ParamTypes) && fti.ParamTypes[i].IsTyped() {
456-
// Target param is typed — ensure arg matches.
457459
if argType == fti.ParamTypes[i] {
458-
result[i] = a // Already the right type.
460+
result[i] = a
459461
} else if argType.IsTyped() && argType.IsNumeric() && fti.ParamTypes[i].IsNumeric() {
460-
// Numeric promotion.
461462
if fti.ParamTypes[i] == TypeFloat && argType == TypeInt {
462-
result[i] = fmt.Sprintf("float64(%s)", a)
463+
result[i] = GoCastExpr{Type: "float64", Value: a}
463464
} else if fti.ParamTypes[i] == TypeInt && argType == TypeFloat {
464-
result[i] = fmt.Sprintf("int(%s)", a)
465+
result[i] = GoCastExpr{Type: "int", Value: a}
465466
} else {
466467
result[i] = a
467468
}
468469
} else if argType.IsTyped() {
469-
// Type mismatch — shouldn't happen with correct inference,
470-
// but be safe.
471470
result[i] = a
472471
} else {
473-
// Arg is interface{} but param is typed — need type assertion.
474-
result[i] = fmt.Sprintf("%s.(%s)", a, fti.ParamTypes[i].GoType())
472+
result[i] = GoTypeAssert{Value: a, Type: fti.ParamTypes[i].GoType()}
475473
}
476474
} else {
477-
// Target param is interface{} — box typed args.
478-
result[i] = g.boxed(a, argType)
475+
if argType.IsTyped() {
476+
result[i] = GoCastExpr{Type: "interface{}", Value: a}
477+
} else {
478+
result[i] = a
479+
}
479480
}
480481
}
481-
return strings.Join(result, ", ")
482+
return result
482483
}

compiler/codegen_build.go

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -597,23 +597,6 @@ func (g *codeGen) buildPanicHandler() GoDeferStmt {
597597
}}
598598
}
599599

600-
// buildMainFunc builds the main() function declaration.
601-
func (g *codeGen) buildMainFunc(topStmts []ast.Statement) (GoFuncDecl, error) {
602-
var body []GoStmt
603-
body = append(body, g.buildPanicHandler())
604-
605-
g.pushScope()
606-
stmts, err := g.buildStmts(topStmts)
607-
if err != nil {
608-
g.popScope()
609-
return GoFuncDecl{}, err
610-
}
611-
body = append(body, stmts...)
612-
g.popScope()
613-
614-
return GoFuncDecl{Name: "main", Body: body}, nil
615-
}
616-
617600
// buildImports constructs the GoImport list for a Rugo program.
618601
func (g *codeGen) buildImports(needsSync, needsTime bool) []GoImport {
619602
var imports []GoImport

0 commit comments

Comments
 (0)