From c90023d6d940a55d9360b974093eaf723377e0c3 Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Fri, 15 Sep 2023 18:49:43 -0400 Subject: [PATCH] Simplify ast structure --- pkg/assembler/assembler.go | 52 +++++++-------- pkg/assembler/grammar.go | 69 ++++++------------- pkg/assembler/grammar_test.go | 122 +++++++++++++++------------------- 3 files changed, 100 insertions(+), 143 deletions(-) diff --git a/pkg/assembler/assembler.go b/pkg/assembler/assembler.go index 02b51ce18..fcba0c88a 100644 --- a/pkg/assembler/assembler.go +++ b/pkg/assembler/assembler.go @@ -68,7 +68,7 @@ func encodeCasmProgram(casmAst CasmProgram) ([]*f.Element, error) { func encodeInstruction(bytecode []*f.Element, instruction Instruction) ([]*f.Element, error) { var encode uint64 = 0 - expression := instruction.Unwrap().Expression() + expression := instruction.Expression() encode, err := encodeDstReg(&instruction, encode) if err != nil { @@ -101,18 +101,18 @@ func encodeInstruction(bytecode []*f.Element, instruction Instruction) ([]*f.Ele } func encodeDstReg(instr *Instruction, encode uint64) (uint64, error) { - if instr.ApPlus != nil || instr.Core.Jump != nil { + if instr.ApPlus != nil || instr.Jump != nil { // dstOffset is not involved so it is set to fp - 1 as default value encode |= 1 << dstRegBit encode |= uint64(biasedMinusOne) return encode, nil } - if instr.Core.Call != nil { + if instr.Call != nil { // dstOffset is set to ap + 0 encode |= uint64(biasedZero) return encode, nil } - if instr.Core.Ret != nil { + if instr.Ret != nil { // dstOffset is set as fp - 2 encode |= 1 << dstRegBit encode |= uint64(biasedMinusTwo) @@ -120,10 +120,10 @@ func encodeDstReg(instr *Instruction, encode uint64) (uint64, error) { } var deref *Deref - if instr.Core.AssertEq != nil { - deref = instr.Core.AssertEq.Dst - } else if instr.Core.Jnz != nil { - deref = instr.Core.Jnz.Condition + if instr.AssertEq != nil { + deref = instr.AssertEq.Dst + } else if instr.Jnz != nil { + deref = instr.Jnz.Condition } biasedOffset, err := deref.BiasedOffset() @@ -140,12 +140,12 @@ func encodeDstReg(instr *Instruction, encode uint64) (uint64, error) { } func encodeOp0Reg(instr *Instruction, expr Expressioner, encode uint64) (uint64, error) { - if instr.Core != nil && instr.Core.Call != nil { + if instr != nil && instr.Call != nil { // op0 is set as [ap + 1] to store current pc encode |= uint64(biasedPlusOne) << op0Offset return encode, nil } - if (instr.Core != nil && (instr.Core.Jnz != nil || instr.Core.Ret != nil)) || + if (instr != nil && (instr.Jnz != nil || instr.Ret != nil)) || (expr.AsDeref() != nil || expr.AsImmediate() != nil) { // op0 is not involved, it is set as fp - 1 as default value encode |= 1 << op0RegBit @@ -175,7 +175,7 @@ func encodeOp0Reg(instr *Instruction, expr Expressioner, encode uint64) (uint64, // Given the expression and the current encode returns an updated encode with the corresponding bit // and offset of op1, an immeadiate if exists, and a possible error func encodeOp1Source(inst *Instruction, expr Expressioner, encode uint64) (uint64, *f.Element, error) { - if inst.Core != nil && inst.Core.Ret != nil { + if inst != nil && inst.Ret != nil { // op1 is set as [fp - 1], where we read the previous pc encode |= uint64(biasedMinusOne) << op1Offset encode |= 1 << op1FpBit @@ -226,25 +226,21 @@ func encodeResLogic(expression Expressioner, encode uint64) uint64 { } func encodePcUpdate(instruction Instruction, encode uint64) uint64 { - if instruction.Core == nil { - return encode - } - - if instruction.Core.Jump != nil || instruction.Core.Call != nil { + if instruction.Jump != nil || instruction.Call != nil { var isAbs bool - if instruction.Core.Jump != nil { - isAbs = instruction.Core.Jump.JumpType == "abs" + if instruction.Jump != nil { + isAbs = instruction.Jump.JumpType == "abs" } else { - isAbs = instruction.Core.Call.CallType == "abs" + isAbs = instruction.Call.CallType == "abs" } if isAbs { encode |= 1 << pcJumpAbsBit } else { encode |= 1 << pcJumpRelBit } - } else if instruction.Core.Jnz != nil { + } else if instruction.Jnz != nil { encode |= 1 << pcJnzBit - } else if instruction.Core.Ret != nil { + } else if instruction.Ret != nil { encode |= 1 << pcJumpAbsBit } @@ -261,14 +257,12 @@ func encodeApUpdate(instruction Instruction, encode uint64) uint64 { } func encodeOpCode(instruction Instruction, encode uint64) uint64 { - if instruction.Core != nil { - if instruction.Core.Call != nil { - encode |= 1 << opcodeCallBit - } else if instruction.Core.Ret != nil { - encode |= 1 << opcodeRetBit - } else if instruction.Core.AssertEq != nil { - encode |= 1 << opcodeAssertEqBit - } + if instruction.Call != nil { + encode |= 1 << opcodeCallBit + } else if instruction.Ret != nil { + encode |= 1 << opcodeRetBit + } else if instruction.AssertEq != nil { + encode |= 1 << opcodeAssertEqBit } return encode } diff --git a/pkg/assembler/grammar.go b/pkg/assembler/grammar.go index 913e19b85..351c5a29a 100644 --- a/pkg/assembler/grammar.go +++ b/pkg/assembler/grammar.go @@ -12,17 +12,13 @@ type CasmProgram struct { } type Instruction struct { - Core *CoreInstruction `@@` - ApPlusOne bool `( "," @"ap" "+" "+" )? ";" |` - ApPlus *ApPlus `@@ ";"` -} - -type CoreInstruction struct { - AssertEq *AssertEq `@@ |` - Jnz *Jnz `@@ |` - Jump *Jump `@@ |` - Call *Call `@@ |` - Ret *Ret `@@ ` + AssertEq *AssertEq `( @@ |` + Jnz *Jnz ` @@ |` + Jump *Jump ` @@ )` + ApPlusOne bool `( "," @"ap" "+" "+" )? ";" |` + Call *Call `( @@ |` + Ret *Ret ` @@ |` + ApPlus *ApPlus ` @@ ) ";"` } type AssertEq struct { @@ -92,45 +88,24 @@ type CoreInstructioner interface { Expression() Expressioner } -func (instruction Instruction) Unwrap() CoreInstructioner { - if instruction.ApPlus != nil { - return instruction.ApPlus - } else if instruction.Core.AssertEq != nil { - return instruction.Core.AssertEq - } else if instruction.Core.Jump != nil { - return instruction.Core.Jump - } else if instruction.Core.Jnz != nil { - return instruction.Core.Jnz - } else if instruction.Core.Call != nil { - return instruction.Core.Call - } else { - return instruction.Core.Ret +func (instruction Instruction) Expression() Expressioner { + switch { + case instruction.AssertEq != nil: + return instruction.AssertEq.Value + case instruction.Jump != nil: + return instruction.Jump.Value + case instruction.Jnz != nil: + return instruction.Jnz.Value + case instruction.Call != nil: + return instruction.Call.Value + case instruction.ApPlus != nil: + return instruction.ApPlus.Value + default: + // when instruction is Ret + return nil } } -func (assertEq *AssertEq) Expression() Expressioner { - return assertEq.Value -} - -func (jump *Jump) Expression() Expressioner { - return jump.Value -} - -func (jnz *Jnz) Expression() Expressioner { - return jnz.Value -} - -func (call *Call) Expression() Expressioner { - return call.Value -} - -func (ret *Ret) Expression() Expressioner { - return nil -} -func (apPlus *ApPlus) Expression() Expressioner { - return apPlus.Value -} - type Expressioner interface { AsDeref() *Deref AsDoubleDeref() *DoubleDeref diff --git a/pkg/assembler/grammar_test.go b/pkg/assembler/grammar_test.go index 088a8e45e..a38d832e5 100644 --- a/pkg/assembler/grammar_test.go +++ b/pkg/assembler/grammar_test.go @@ -17,22 +17,20 @@ func TestAssertEqualWithRegisterGrammar(t *testing.T) { &CasmProgram{ []Instruction{ { - Core: &CoreInstruction{ - AssertEq: &AssertEq{ - Dst: &Deref{ - Name: "fp", + AssertEq: &AssertEq{ + Dst: &Deref{ + Name: "fp", + Offset: &Offset{ + Sign: "+", + Value: ptrOf(3), + }, + }, + Value: &Expression{ + Deref: &Deref{ + Name: "ap", Offset: &Offset{ Sign: "+", - Value: ptrOf(3), - }, - }, - Value: &Expression{ - Deref: &Deref{ - Name: "ap", - Offset: &Offset{ - Sign: "+", - Value: ptrOf(4), - }, + Value: ptrOf(4), }, }, }, @@ -56,22 +54,20 @@ func TestAssertEqualWithApPlusGrammar(t *testing.T) { &CasmProgram{ []Instruction{ { - Core: &CoreInstruction{ - AssertEq: &AssertEq{ - Dst: &Deref{ - Name: "fp", + AssertEq: &AssertEq{ + Dst: &Deref{ + Name: "fp", + Offset: &Offset{ + Sign: "+", + Value: ptrOf(3), + }, + }, + Value: &Expression{ + Deref: &Deref{ + Name: "ap", Offset: &Offset{ Sign: "+", - Value: ptrOf(3), - }, - }, - Value: &Expression{ - Deref: &Deref{ - Name: "ap", - Offset: &Offset{ - Sign: "+", - Value: ptrOf(4), - }, + Value: ptrOf(4), }, }, }, @@ -95,19 +91,17 @@ func TestAssertEqualWithImmediateGrammar(t *testing.T) { &CasmProgram{ []Instruction{ { - Core: &CoreInstruction{ - AssertEq: &AssertEq{ - Dst: &Deref{ - Name: "fp", - Offset: &Offset{ - Sign: "+", - Value: ptrOf(1), - }, - }, - Value: &Expression{ - Immediate: ptrOf("5"), + AssertEq: &AssertEq{ + Dst: &Deref{ + Name: "fp", + Offset: &Offset{ + Sign: "+", + Value: ptrOf(1), }, }, + Value: &Expression{ + Immediate: ptrOf("5"), + }, }, ApPlusOne: false, }, @@ -128,26 +122,24 @@ func TestAssertEqualWithMathOperationGrammar(t *testing.T) { &CasmProgram{ []Instruction{ { - Core: &CoreInstruction{ - AssertEq: &AssertEq{ - Dst: &Deref{ - Name: "ap", - Offset: nil, - }, - Value: &Expression{ - MathOperation: &MathOperation{ - Lhs: &Deref{ - Name: "fp", - Offset: &Offset{ - Sign: "+", - Value: ptrOf(7), - }, - }, - Operator: "+", - Rhs: &DerefOrImm{ - Immediate: ptrOf("5"), + AssertEq: &AssertEq{ + Dst: &Deref{ + Name: "ap", + Offset: nil, + }, + Value: &Expression{ + MathOperation: &MathOperation{ + Lhs: &Deref{ + Name: "fp", + Offset: &Offset{ + Sign: "+", + Value: ptrOf(7), }, }, + Operator: "+", + Rhs: &DerefOrImm{ + Immediate: ptrOf("5"), + }, }, }, }, @@ -170,12 +162,10 @@ func TestCallAbsGrammar(t *testing.T) { &CasmProgram{ []Instruction{ { - Core: &CoreInstruction{ - Call: &Call{ - CallType: "abs", - Value: &DerefOrImm{ - Immediate: ptrOf("123"), - }, + Call: &Call{ + CallType: "abs", + Value: &DerefOrImm{ + Immediate: ptrOf("123"), }, }, ApPlusOne: false, @@ -197,10 +187,8 @@ func TestRetGrammar(t *testing.T) { &CasmProgram{ []Instruction{ { - Core: &CoreInstruction{ - Ret: &Ret{ - Ret: "", - }, + Ret: &Ret{ + Ret: "", }, ApPlusOne: false, },