Skip to content

Commit 088c12a

Browse files
committed
refactor(compiler): clarify conditional or lowering
Rename conditional OR token/parser labels and shorten the fallback-yield lowering helpers so the control flow is easier to follow. Keep comments focused on ownership and value-position behavior rather than restating helper names.
1 parent eb822cf commit 088c12a

6 files changed

Lines changed: 76 additions & 89 deletions

File tree

ast/ast.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ type InfixExpression struct {
447447

448448
// IsLogicalOr reports whether ie is a logical OR infix expression.
449449
func (ie *InfixExpression) IsLogicalOr() bool {
450-
return ie.Operator == token.SYM_LOGICAL_OR
450+
return ie.Operator == token.SYM_COND_OR
451451
}
452452

453453
// IsLogicalOr returns exp as an infix logical OR expression.

compiler/array.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,7 @@ func (c *Compiler) compileArrayRangeRanges(info *ExprInfo, dest []*ast.Identifie
950950
output := outputs[0]
951951

952952
withCollectorPreparedLoopNest(c, info.Rewrite.(*ast.ArrayRangeExpression), info.Ranges, nil, nil, func(rew *ast.ArrayRangeExpression) {
953-
c.compileOperandCondExprValue(rew, llvm.Value{}, func() {
953+
c.compileCondOperands(rew, llvm.Value{}, func() {
954954
arraySym, idxSym, arrType := c.compileArrayRangeOperands(rew)
955955
// Source operands are temporary for each loop iteration in this path.
956956
defer c.freeTemporary(rew.Array, []*Symbol{arraySym})

compiler/compiler.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1849,7 +1849,7 @@ func (c *Compiler) compileInfixRanges(expr *ast.InfixExpression, info *ExprInfo,
18491849
c.pushBoundsGuard("infix_iter_bounds_guard")
18501850
defer c.popBoundsGuard()
18511851

1852-
c.compileOperandCondExprValue(prepared, llvm.Value{}, func() {
1852+
c.compileCondOperands(prepared, llvm.Value{}, func() {
18531853
left := c.compileExpression(leftRew, nil)
18541854
right := c.compileExpression(rightRew, nil)
18551855

@@ -2118,7 +2118,7 @@ func (c *Compiler) compilePrefixRanges(expr *ast.PrefixExpression, info *ExprInf
21182118
c.pushBoundsGuard("prefix_iter_bounds_guard")
21192119
defer c.popBoundsGuard()
21202120

2121-
c.compileOperandCondExprValue(prepared, llvm.Value{}, func() {
2121+
c.compileCondOperands(prepared, llvm.Value{}, func() {
21222122
ops := c.compileExpression(rightRew, nil)
21232123

21242124
for i := 0; i < len(ops); i++ {

compiler/cond.go

Lines changed: 39 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ func (c *Compiler) hasCondExprInTree(expr ast.Expression) bool {
415415
return false
416416
}
417417

418-
func (c *Compiler) logicalOrCondExpr(expr ast.Expression) (*ast.InfixExpression, bool) {
418+
func (c *Compiler) fallbackOrExpr(expr ast.Expression) (*ast.InfixExpression, bool) {
419419
infix, ok := ast.IsLogicalOr(expr)
420420
if !ok {
421421
return nil, false
@@ -425,12 +425,12 @@ func (c *Compiler) logicalOrCondExpr(expr ast.Expression) (*ast.InfixExpression,
425425
return infix, info.HasFallbackOr()
426426
}
427427

428-
func (c *Compiler) hasLogicalOrCondExprInTree(expr ast.Expression) bool {
429-
if _, ok := c.logicalOrCondExpr(expr); ok {
428+
func (c *Compiler) hasFallbackOrInTree(expr ast.Expression) bool {
429+
if _, ok := c.fallbackOrExpr(expr); ok {
430430
return true
431431
}
432432
for _, child := range ast.ExprChildren(expr) {
433-
if c.hasLogicalOrCondExprInTree(child) {
433+
if c.hasFallbackOrInTree(child) {
434434
return true
435435
}
436436
}
@@ -462,31 +462,26 @@ func (c *Compiler) handleComparisons(op string, left, right []*Symbol, info *Exp
462462
return lhsSyms, cond
463463
}
464464

465-
// extractCondExprs walks the expression tree, evaluates each CondScalar
466-
// comparison, ANDs results into cond, and stores LHS values in the
467-
// statement-local condLHS map for substitution during later value compilation.
468-
// LHS temporaries are appended to temps so the caller can free them on the
469-
// false path.
465+
// extractCondExprs evaluates value-position comparisons and stores their LHS
466+
// values for substitution during later value compilation.
470467
func (c *Compiler) extractCondExprs(expr ast.Expression, cond llvm.Value, temps []condTemp) (llvm.Value, []condTemp) {
471468
info := c.ExprCache[key(c.FuncNameMangled, expr)]
472469

473-
// Handle conditional expression (comparison in value position).
474470
// Comparisons with ranges can be extracted only when all required iterators
475471
// are already bound by an outer loop (no pending ranges).
476472
if infix, ok := expr.(*ast.InfixExpression); ok && info.HasCondScalar() && len(c.pendingLoopRanges(info.Ranges)) == 0 {
477473
cond, temps = c.extractCondExprs(infix.Left, cond, temps)
478474
cond, temps = c.extractCondExprs(infix.Right, cond, temps)
479-
return c.extractInfixCondExpr(infix, info, cond, temps)
475+
return c.extractCondComparison(infix, info, cond, temps)
480476
}
481477

482-
// Not a conditional expression — recurse into children
483478
for _, child := range ast.ExprChildren(expr) {
484479
cond, temps = c.extractCondExprs(child, cond, temps)
485480
}
486481
return cond, temps
487482
}
488483

489-
func (c *Compiler) extractInfixCondExpr(infix *ast.InfixExpression, info *ExprInfo, cond llvm.Value, temps []condTemp) (llvm.Value, []condTemp) {
484+
func (c *Compiler) extractCondComparison(infix *ast.InfixExpression, info *ExprInfo, cond llvm.Value, temps []condTemp) (llvm.Value, []condTemp) {
490485
left := c.compileExpression(infix.Left, nil)
491486
right := c.compileExpression(infix.Right, nil)
492487

@@ -495,8 +490,8 @@ func (c *Compiler) extractInfixCondExpr(infix *ast.InfixExpression, info *ExprIn
495490

496491
c.requireCondLHSFrame()[key(c.FuncNameMangled, infix)] = lhsSyms
497492
temps = append(temps, condTemp{infix.Left, left})
498-
// Free right-side temporaries (only used for comparison).
499-
// Left-side values are retained in condLHS for later substitution.
493+
494+
// Right is comparison-only; left is retained for condLHS substitution.
500495
c.freeTemporary(infix.Right, right)
501496
return cond, temps
502497
}
@@ -517,36 +512,28 @@ func (c *Compiler) cleanupCondExprElse(temps []condTemp) {
517512
}
518513
}
519514

520-
// compileCondExprValue extracts cond-expr predicates for expr, branches through
521-
// value-position conditions, and compiles onTrue on admitted paths only. Plain
522-
// comparisons compose as AND; value-position logical OR tries the left operand
523-
// first and falls back to the right operand only on the left false path.
515+
// compileCondExprValue gates value-position cond expressions. Comparisons
516+
// compose as AND; fallback OR tries the right side only after the left fails.
524517
func (c *Compiler) compileCondExprValue(expr ast.Expression, baseCond llvm.Value, onTrue func()) {
525518
c.pushCondLHSFrame()
526519
defer c.popCondLHSFrame()
527520

528-
c.compileCondExprValueInFrame(expr, baseCond, onTrue)
529-
}
530-
531-
func (c *Compiler) compileCondExprValueInFrame(expr ast.Expression, baseCond llvm.Value, onTrue func()) {
532-
if c.hasLogicalOrCondExprInTree(expr) {
533-
c.compileCondExprWithFailure(expr, baseCond, onTrue, func() {})
521+
if c.hasFallbackOrInTree(expr) {
522+
c.compileYield(expr, baseCond, onTrue, func() {})
534523
return
535524
}
536525

537526
cond, temps := c.extractCondExprs(expr, baseCond, nil)
538-
c.compileCondExprBranch(cond, temps, onTrue, func() {})
527+
c.branchCond(cond, temps, onTrue, func() {})
539528
}
540529

541-
// compileOperandCondExprValue extracts conditional expressions from expr's
542-
// operands while leaving expr itself to the caller. Use this when the caller is
543-
// compiling the root operation into an already-seeded output slot.
544-
func (c *Compiler) compileOperandCondExprValue(expr ast.Expression, baseCond llvm.Value, onTrue func()) {
530+
// compileCondOperands leaves expr itself to the caller.
531+
func (c *Compiler) compileCondOperands(expr ast.Expression, baseCond llvm.Value, onTrue func()) {
545532
c.pushCondLHSFrame()
546533
defer c.popCondLHSFrame()
547534

548-
if c.hasLogicalOrCondExprInTree(expr) {
549-
c.compileCondExprChildrenInFrame(ast.ExprChildren(expr), baseCond, onTrue, func() {})
535+
if c.hasFallbackOrInTree(expr) {
536+
c.compileChildYields(ast.ExprChildren(expr), baseCond, onTrue, func() {})
550537
return
551538
}
552539

@@ -555,10 +542,10 @@ func (c *Compiler) compileOperandCondExprValue(expr ast.Expression, baseCond llv
555542
for _, child := range ast.ExprChildren(expr) {
556543
cond, temps = c.extractCondExprs(child, cond, temps)
557544
}
558-
c.compileCondExprBranch(cond, temps, onTrue, func() {})
545+
c.branchCond(cond, temps, onTrue, func() {})
559546
}
560547

561-
func (c *Compiler) compileCondExprBranch(cond llvm.Value, temps []condTemp, onTrue func(), onFalse func()) {
548+
func (c *Compiler) branchCond(cond llvm.Value, temps []condTemp, onTrue func(), onFalse func()) {
562549
if cond.IsNil() {
563550
onTrue()
564551
return
@@ -578,42 +565,42 @@ func (c *Compiler) compileCondExprBranch(cond llvm.Value, temps []condTemp, onTr
578565
c.builder.SetInsertPointAtEnd(contBlock)
579566
}
580567

581-
func (c *Compiler) compileCondExprChildrenInFrame(children []ast.Expression, baseCond llvm.Value, onTrue func(), onFalse func()) {
568+
func (c *Compiler) compileChildYields(children []ast.Expression, baseCond llvm.Value, onTrue func(), onFalse func()) {
582569
if len(children) == 0 {
583-
c.compileCondExprBranch(baseCond, nil, onTrue, onFalse)
570+
c.branchCond(baseCond, nil, onTrue, onFalse)
584571
return
585572
}
586573

587574
child := children[0]
588575
rest := children[1:]
589576
if c.hasCondExprInTree(child) {
590-
c.compileCondExprWithFailure(child, baseCond, func() {
591-
c.compileCondExprChildrenInFrame(rest, llvm.Value{}, onTrue, onFalse)
577+
c.compileYield(child, baseCond, func() {
578+
c.compileChildYields(rest, llvm.Value{}, onTrue, onFalse)
592579
}, onFalse)
593580
return
594581
}
595582

596-
c.compileCondExprChildrenInFrame(rest, baseCond, onTrue, onFalse)
583+
c.compileChildYields(rest, baseCond, onTrue, onFalse)
597584
}
598585

599-
func (c *Compiler) compileCondExprWithFailure(expr ast.Expression, baseCond llvm.Value, onTrue func(), onFalse func()) {
600-
if logicalOr, ok := c.logicalOrCondExpr(expr); ok {
601-
c.compileLogicalOrCondExprWithFailure(logicalOr, baseCond, onTrue, onFalse)
586+
func (c *Compiler) compileYield(expr ast.Expression, baseCond llvm.Value, onTrue func(), onFalse func()) {
587+
if logicalOr, ok := c.fallbackOrExpr(expr); ok {
588+
c.compileFallbackOr(logicalOr, baseCond, onTrue, onFalse)
602589
return
603590
}
604591

605-
if !c.hasLogicalOrCondExprInTree(expr) {
592+
if !c.hasFallbackOrInTree(expr) {
606593
cond, temps := c.extractCondExprs(expr, baseCond, nil)
607-
c.compileCondExprBranch(cond, temps, onTrue, onFalse)
594+
c.branchCond(cond, temps, onTrue, onFalse)
608595
return
609596
}
610597

611-
c.compileCondExprChildrenInFrame(ast.ExprChildren(expr), baseCond, func() {
598+
c.compileChildYields(ast.ExprChildren(expr), baseCond, func() {
612599
if infix, ok := expr.(*ast.InfixExpression); ok {
613600
info := c.ExprCache[key(c.FuncNameMangled, infix)]
614601
if info != nil && info.HasCondScalar() && len(c.pendingLoopRanges(info.Ranges)) == 0 {
615-
cond, temps := c.extractInfixCondExpr(infix, info, llvm.Value{}, nil)
616-
c.compileCondExprBranch(cond, temps, onTrue, onFalse)
602+
cond, temps := c.extractCondComparison(infix, info, llvm.Value{}, nil)
603+
c.branchCond(cond, temps, onTrue, onFalse)
617604
return
618605
}
619606
}
@@ -630,10 +617,10 @@ func (c *Compiler) withCondLHS(expr ast.Expression, syms []*Symbol, body func())
630617
body()
631618
}
632619

633-
func (c *Compiler) compileLogicalOrCondExprWithFailure(expr *ast.InfixExpression, baseCond llvm.Value, onTrue func(), onFalse func()) {
620+
func (c *Compiler) compileFallbackOr(expr *ast.InfixExpression, baseCond llvm.Value, onTrue func(), onFalse func()) {
634621
if !baseCond.IsNil() {
635-
c.compileCondExprBranch(baseCond, nil, func() {
636-
c.compileLogicalOrCondExprWithFailure(expr, llvm.Value{}, onTrue, onFalse)
622+
c.branchCond(baseCond, nil, func() {
623+
c.compileFallbackOr(expr, llvm.Value{}, onTrue, onFalse)
637624
}, onFalse)
638625
return
639626
}
@@ -647,8 +634,8 @@ func (c *Compiler) compileLogicalOrCondExprWithFailure(expr *ast.InfixExpression
647634
c.withCondLHS(expr, right, onTrue)
648635
}
649636

650-
c.compileCondExprWithFailure(expr.Left, llvm.Value{}, leftTrue, func() {
651-
c.compileCondExprWithFailure(expr.Right, llvm.Value{}, rightTrue, onFalse)
637+
c.compileYield(expr.Left, llvm.Value{}, leftTrue, func() {
638+
c.compileYield(expr.Right, llvm.Value{}, rightTrue, onFalse)
652639
})
653640
}
654641

parser/parser.go

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const (
1717
LOWEST = 0.0 + iota // iota works with floats when used in a float expression
1818
ASSIGN // =
1919
COMMA // ,
20-
LOGICAL_OR // ||
20+
COND_OR // ||
2121
BITWISE_OR // |
2222
BITWISE_XOR // ⊕
2323
BITWISE_AND // &
@@ -34,32 +34,32 @@ const (
3434

3535
// leftBindingPower: how strongly an operator binds to its left operand
3636
var leftBindingPower = map[string]float64{
37-
token.SYM_ASSIGN: ASSIGN,
38-
token.SYM_COMMA: COMMA,
39-
token.SYM_LOGICAL_OR: LOGICAL_OR,
40-
token.SYM_OR: BITWISE_OR,
41-
token.SYM_XOR: BITWISE_XOR,
42-
token.SYM_AND: BITWISE_AND,
43-
token.SYM_SHL: SHIFT,
44-
token.SYM_SHR: SHIFT,
45-
token.SYM_ASR: SHIFT,
46-
token.SYM_ADD: SUM,
47-
token.SYM_SUB: SUM,
48-
token.SYM_CONCAT: SUM, // ⊕ array concatenation
49-
token.SYM_MUL: PRODUCT,
50-
token.SYM_DIV: PRODUCT,
51-
token.SYM_QUO: PRODUCT,
52-
token.SYM_MOD: PRODUCT,
53-
token.SYM_IMPL_MUL: EXP - 0.25, // 8.75: Between RBP(^)=8.5 and EXP=9, allows ⋅ in exponents but not on left of ^
54-
token.SYM_EXP: EXP,
55-
token.SYM_COLON: COLON,
56-
token.SYM_EQL: LESSGREATER,
57-
token.SYM_LSS: LESSGREATER,
58-
token.SYM_GTR: LESSGREATER,
59-
token.SYM_NEQ: LESSGREATER,
60-
token.SYM_LEQ: LESSGREATER,
61-
token.SYM_GEQ: LESSGREATER,
62-
token.SYM_LPAREN: CALL,
37+
token.SYM_ASSIGN: ASSIGN,
38+
token.SYM_COMMA: COMMA,
39+
token.SYM_COND_OR: COND_OR,
40+
token.SYM_OR: BITWISE_OR,
41+
token.SYM_XOR: BITWISE_XOR,
42+
token.SYM_AND: BITWISE_AND,
43+
token.SYM_SHL: SHIFT,
44+
token.SYM_SHR: SHIFT,
45+
token.SYM_ASR: SHIFT,
46+
token.SYM_ADD: SUM,
47+
token.SYM_SUB: SUM,
48+
token.SYM_CONCAT: SUM, // ⊕ array concatenation
49+
token.SYM_MUL: PRODUCT,
50+
token.SYM_DIV: PRODUCT,
51+
token.SYM_QUO: PRODUCT,
52+
token.SYM_MOD: PRODUCT,
53+
token.SYM_IMPL_MUL: EXP - 0.25, // 8.75: Between RBP(^)=8.5 and EXP=9, allows ⋅ in exponents but not on left of ^
54+
token.SYM_EXP: EXP,
55+
token.SYM_COLON: COLON,
56+
token.SYM_EQL: LESSGREATER,
57+
token.SYM_LSS: LESSGREATER,
58+
token.SYM_GTR: LESSGREATER,
59+
token.SYM_NEQ: LESSGREATER,
60+
token.SYM_LEQ: LESSGREATER,
61+
token.SYM_GEQ: LESSGREATER,
62+
token.SYM_LPAREN: CALL,
6363
}
6464

6565
// rightBindingPower: how strongly an operator binds to its right operand
@@ -127,7 +127,7 @@ func New(l *lexer.Lexer) *StmtParser {
127127
p.infixParseFns = make(map[string]infixParseFn)
128128
p.registerInfix(token.SYM_COLON, p.parseRangeLiteral)
129129

130-
p.registerInfix(token.SYM_LOGICAL_OR, p.parseInfixExpression)
130+
p.registerInfix(token.SYM_COND_OR, p.parseInfixExpression)
131131
p.registerInfix(token.SYM_OR, p.parseInfixExpression)
132132
p.registerInfix(token.SYM_XOR, p.parseInfixExpression)
133133
p.registerInfix(token.SYM_AND, p.parseInfixExpression)

token/token.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ const (
9090
SYM_GEQ = ">="
9191

9292
// logical and bitwise symbols
93-
SYM_LOGICAL_OR = "||"
94-
SYM_AND = "&"
95-
SYM_OR = "|"
96-
SYM_XOR = "⊻"
97-
SYM_TILDE = "~"
93+
SYM_COND_OR = "||"
94+
SYM_AND = "&"
95+
SYM_OR = "|"
96+
SYM_XOR = "⊻"
97+
SYM_TILDE = "~"
9898

9999
// array concatenation
100100
SYM_CONCAT = "⊕"

0 commit comments

Comments
 (0)