Skip to content

Commit 1e72a8b

Browse files
authored
feat: add label in macro ite, add case in linker, add example test fo… (#1343)
* feat: add label in macro ite, add case in linker, add example test for ternary operator using a const * feat: clean and add test * feat: panic for register on rhs * feat: factorize cases for linker * feat: syntax error vs panic + fix linting * feat: use ternary feature in TRM module * fix: linker
1 parent bd3d8c8 commit 1e72a8b

File tree

7 files changed

+62
-10
lines changed

7 files changed

+62
-10
lines changed

pkg/asm/assembler/linker.go

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,14 +203,21 @@ func (p *Linker) linkInstruction(insn macro.Instruction, buses map[uint]io.Bus)
203203
return p.linkExprs(insn.Sources)
204204
case *macro.IfGoto:
205205
if insn.Label != "" {
206-
deats, ok := p.constmap[module.NewName(insn.Label, 1)]
207-
//
208-
if !ok {
209-
msg := fmt.Sprintf("unknown register or constant \"%s\"", insn.Label)
210-
return p.srcmap.SyntaxError(insn, msg)
206+
value, errmsg := p.getLabelValue(insn.Label)
207+
if errmsg != "" {
208+
return p.srcmap.SyntaxError(insn, errmsg)
209+
} else {
210+
insn.Constant = value
211+
}
212+
}
213+
case *macro.IfThenElse:
214+
if insn.Label != "" {
215+
value, errmsg := p.getLabelValue(insn.Label)
216+
if errmsg != "" {
217+
return p.srcmap.SyntaxError(insn, errmsg)
218+
} else {
219+
insn.Right = value
211220
}
212-
//
213-
insn.Constant = deats.Left
214221
}
215222
default:
216223
// continue
@@ -257,6 +264,21 @@ func (p *Linker) linkExprs(es []macro.Expr) *source.SyntaxError {
257264
return nil
258265
}
259266

267+
func (p *Linker) getLabelValue(l string) (big.Int, string) {
268+
var deats util.Pair[big.Int, uint]
269+
//
270+
var ok bool
271+
//
272+
deats, ok = p.constmap[module.NewName(l, 1)]
273+
//
274+
if !ok {
275+
msg := fmt.Sprintf("unknown register or constant \"%s\"", l)
276+
return big.Int{}, msg
277+
}
278+
//
279+
return deats.Left, ""
280+
}
281+
260282
// Get the local bus declared for the given function, either by allocating a new
261283
// bus (if was not already allocated) or returning the existing bus (if it was
262284
// previously allocated). Allocating a new bus requires allocating

pkg/asm/assembler/parser.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,9 @@ func (p *Parser) parseTernaryRhs(targets []io.RegisterId, env *Environment) (mac
573573
var (
574574
errs []source.SyntaxError
575575
lhs io.RegisterId
576+
rhsExpr macro.Expr
576577
rhs, tb, fb big.Int
578+
label string
577579
cond uint8
578580
)
579581
// Parse left hand side
@@ -585,9 +587,19 @@ func (p *Parser) parseTernaryRhs(targets []io.RegisterId, env *Environment) (mac
585587
return nil, errs
586588
}
587589
// Parse right hand side
588-
if rhs, errs = p.parseNumber(env); len(errs) > 0 {
590+
if rhsExpr, errs = p.parseAtomicExpr(env); len(errs) > 0 {
589591
return nil, errs
590592
}
593+
// Dispatch on rhs expression form
594+
switch e := rhsExpr.(type) {
595+
case *expr.Const:
596+
rhs = e.Constant
597+
label = e.Label
598+
case *expr.RegAccess:
599+
// We can invoke (p.index - 1) as we are in the case of a ternary operator
600+
// Checks are already performed to have a lhs
601+
return nil, p.syntaxErrors(p.tokens[p.index-1], "ternary operator does not support register on the rhs")
602+
}
591603
// expect question mark
592604
if _, errs = p.expect(QMARK); len(errs) > 0 {
593605
return nil, errs
@@ -610,6 +622,7 @@ func (p *Parser) parseTernaryRhs(targets []io.RegisterId, env *Environment) (mac
610622
Cond: cond,
611623
Left: lhs,
612624
Right: rhs,
625+
Label: label,
613626
Then: tb,
614627
Else: fb,
615628
}, nil

pkg/asm/io/macro/ite.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ type IfThenElse struct {
3131
Left io.RegisterId
3232
// Right-hand side
3333
Right big.Int
34+
// Constant label
35+
Label string
3436
// Then/Else branches
3537
Then, Else big.Int
3638
}

pkg/test/assembly_util_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,8 @@ func Test_AsmUtil_SetByte(t *testing.T) {
6262
func Test_AsmUtil_Signextend(t *testing.T) {
6363
util.CheckWithFields(t, false, "asm/util/signextend", util.ASM_MAX_PADDING, field.BLS12_377, field.KOALABEAR_16)
6464
}
65+
66+
// Note: field.KOALABEAR_16 is omitted as it's causing an issue with register splitting for the ternary operator
67+
func Test_AsmUtil_Ternary(t *testing.T) {
68+
util.CheckWithFields(t, false, "asm/util/ternary", util.ASM_MAX_PADDING, field.BLS12_377)
69+
}

testdata/asm/bench/trm.zkasm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const MAX_PRC_CONTIGUOUS_ADDRESS = 0x11
2-
;; const P256_VERIFY_ADDRESS = 0x100
2+
const P256_VERIFY_ADDRESS = 0x100
33

44
;; The address trimming module does two things: (i) reduce 256bit
55
;; addresses into u160 addresses (i.e. modulo 2^160); (b) identify
@@ -38,7 +38,7 @@ fn trm(RAW_ADDRESS u256) -> (ADDRESS_HI u32, IS_PRECOMPILE u1) {
3838
IS_PRECOMPILE=1
3939
return
4040
check_p256_verify:
41-
IS_PRECOMPILE = low == 0x100 ? 1 : 0
41+
IS_PRECOMPILE = low == P256_VERIFY_ADDRESS ? 1 : 0
4242
return
4343
exit_0:
4444
;; no, not precompile

testdata/asm/util/ternary.accepts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{"ternary_test": { "value": [199], "result": [0] }}
2+
{"ternary_test": { "value": [200], "result": [1] }}
3+
{"ternary_test": { "value": [201], "result": [0] }}

testdata/asm/util/ternary.zkasm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const TWO_HUNDRED = 200
2+
3+
;; ternary_test is using a value u128 to avoid the register splitting error for now
4+
fn ternary_test(value u128) -> (result u1) {
5+
result = value == TWO_HUNDRED ? 1 : 0
6+
return
7+
}

0 commit comments

Comments
 (0)