Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions codegen/codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -1902,9 +1902,21 @@ func (g *Generator) generateAltBlock(alt *ast.AltBlock) {
g.write(fmt.Sprintf("case %s = <-%s:\n", goIdent(c.Variable), goIdent(c.Channel)))
}
g.indent++
guardedSkip := c.IsSkip && c.Guard != nil
if guardedSkip {
g.builder.WriteString(strings.Repeat("\t", g.indent))
g.write("if ")
g.generateExpression(c.Guard)
g.write(" {\n")
g.indent++
}
for _, s := range c.Body {
g.generateStatement(s)
}
if guardedSkip {
g.indent--
g.writeLine("}")
}
g.indent--
}
g.writeLine("}")
Expand Down
53 changes: 53 additions & 0 deletions codegen/e2e_misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,59 @@ func TestE2E_AltGuardedSkip(t *testing.T) {
}
}

func TestE2E_AltGuardedSkipTrue(t *testing.T) {
// Issue #77: ALT with channel case and guarded SKIP where guard is TRUE
// The SKIP fires immediately, then the channel send proceeds
occam := `SEQ
CHAN OF INT c:
INT result:
BOOL ready:
ready := TRUE
result := 0
PAR
SEQ
ALT
ready & SKIP
result := 99
c ? result
SKIP
c ! 42
c ? result
print.int(result)
`
output := transpileCompileRun(t, occam)
expected := "42\n"
if output != expected {
t.Errorf("expected %q, got %q", expected, output)
}
}

func TestE2E_AltGuardedSkipFalse(t *testing.T) {
// Issue #77: ALT with channel case and guarded SKIP where guard is FALSE
// The SKIP guard is false, so the channel case fires
occam := `SEQ
CHAN OF INT c:
INT result:
BOOL ready:
ready := FALSE
result := 0
PAR
SEQ
ALT
ready & SKIP
result := 99
c ? result
SKIP
c ! 77
print.int(result)
`
output := transpileCompileRun(t, occam)
expected := "77\n"
if output != expected {
t.Errorf("expected %q, got %q", expected, output)
}
}

func TestE2E_MultiLineAbbreviation(t *testing.T) {
// Issue #79: IS at end of line as continuation
occam := `SEQ
Expand Down
32 changes: 32 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,38 @@ func TestAltBlockWithGuard(t *testing.T) {
}
}

func TestAltBlockWithGuardedSkip(t *testing.T) {
input := `ALT
ready & SKIP
some.proc()
`
l := lexer.New(input)
p := New(l)
program := p.ParseProgram()
checkParserErrors(t, p)

if len(program.Statements) != 1 {
t.Fatalf("expected 1 statement, got %d", len(program.Statements))
}

alt, ok := program.Statements[0].(*ast.AltBlock)
if !ok {
t.Fatalf("expected AltBlock, got %T", program.Statements[0])
}

if len(alt.Cases) != 1 {
t.Fatalf("expected 1 case, got %d", len(alt.Cases))
}

c := alt.Cases[0]
if !c.IsSkip {
t.Error("expected IsSkip to be true")
}
if c.Guard == nil {
t.Error("expected guard expression, got nil")
}
}

func TestWhileLoop(t *testing.T) {
input := `WHILE x > 0
x := x - 1
Expand Down
Loading