Skip to content

Commit

Permalink
Fix bug for parsing negative immediate values (#148)
Browse files Browse the repository at this point in the history
* added UpdatePc tests and fixed a bug in UpdatePc

* Fixed accessing field value without Read()

* fixed failing tests

* small refactor for TestUpdatePcJump

* initial changes

* fixed test errors

* change immediate parsing to string

* fix DerefOrImm and add tests

* added test in assembler

* minor fix to assembler_test.go

* fix failing test
  • Loading branch information
mmk-1 authored Nov 7, 2023
1 parent f93b6d1 commit 1bfd306
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 11 deletions.
48 changes: 48 additions & 0 deletions pkg/assembler/assembler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,54 @@ func TestAddApImm(t *testing.T) {

}

func TestCallAbsNegative(t *testing.T) {
encode, imm := parseImmediateInstruction("call abs -123;")

expectedImm := f.Element{}
expectedImm.SetInt64(-123)
// verify imm
assert.Equal(t, expectedImm, *imm)

// verify offsets
dstOffset := uint16(encode)
assert.Equal(t, biased(0), dstOffset)

op0Offset := uint16(encode >> 16)
assert.Equal(t, biased(1), op0Offset)

op1Offset := uint16(encode >> 32)
assert.Equal(t, biased(1), op1Offset)

// verify flags
flagsReg := uint16(encode >> flagsOffset)
assert.True(t, (flagsReg>>dstRegBit)&1 == 0)
assert.True(t, (flagsReg>>op0RegBit)&1 == 0)
assert.True(
t,
(flagsReg>>op1ImmBit)&1 == 1 &&
(flagsReg>>op1FpBit)&1 == 0 &&
(flagsReg>>op1ApBit)&1 == 0,
)
assert.True(
t, (flagsReg>>resAddBit)&1 == 0 && (flagsReg>>resMulBit)&1 == 0,
)
assert.True(
t,
(flagsReg>>pcJumpAbsBit)&1 == 1 &&
(flagsReg>>pcJumpRelBit)&1 == 0 &&
(flagsReg>>pcJnzBit)&1 == 0,
)
assert.True(
t, (flagsReg>>apAddBit)&1 == 0 && (flagsReg>>apAdd1Bit)&1 == 0,
)
assert.True(
t,
(flagsReg>>opcodeRetBit)&1 == 0 &&
(flagsReg>>opcodeCallBit)&1 == 1 &&
(flagsReg>>opcodeAssertEqBit)&1 == 0,
)
}

func parseImmediateInstruction(casmCode string) (uint64, *f.Element) {
instructions, err := CasmToBytecode(casmCode)
if err != nil {
Expand Down
35 changes: 27 additions & 8 deletions pkg/assembler/grammar.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ type ApPlus struct {
}

type Expression struct {
DoubleDeref *DoubleDeref `@@ |`
MathOperation *MathOperation `@@ |`
Deref *Deref `@@ |`
Immediate *string `@Int`
DoubleDeref *DoubleDeref `@@ |`
MathOperation *MathOperation `@@ |`
Deref *Deref `@@ |`
Immediate *ImmediateValue `@@`
}

type Deref struct {
Expand All @@ -78,8 +78,13 @@ type MathOperation struct {
}

type DerefOrImm struct {
Deref *Deref `@@ |`
Immediate *string `@Int`
Deref *Deref `@@ |`
Immediate *ImmediateValue `@@`
}

type ImmediateValue struct {
Sign string `@("+" | "-")?`
Value *string `@Int`
}

// AST Functionality
Expand Down Expand Up @@ -126,7 +131,14 @@ func (e *Expression) AsMathOperation() *MathOperation {
}

func (e *Expression) AsImmediate() *string {
return e.Immediate
if e.Immediate == nil {
return nil
}
if e.Immediate.Sign == "-" {
imm := fmt.Sprintf("-%s", *e.Immediate.Value)
return &imm
}
return e.Immediate.Value
}

func (di *DerefOrImm) AsDeref() *Deref {
Expand All @@ -141,7 +153,14 @@ func (di *DerefOrImm) AsMathOperation() *MathOperation {
return nil
}
func (di *DerefOrImm) AsImmediate() *string {
return di.Immediate
if di.Immediate == nil {
return nil
}
if di.Immediate.Sign == "-" {
imm := fmt.Sprintf("-%s", *di.Immediate.Value)
return &imm
}
return di.Immediate.Value
}

func (deref *Deref) IsFp() bool {
Expand Down
77 changes: 74 additions & 3 deletions pkg/assembler/grammar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@ func TestAssertEqualWithImmediateGrammar(t *testing.T) {
},
},
Value: &Expression{
Immediate: ptrOf("5"),
Immediate: &ImmediateValue{
Sign: "",
Value: ptrOf("5"),
},
},
},
ApPlusOne: false,
Expand Down Expand Up @@ -139,7 +142,10 @@ func TestAssertEqualWithMathOperationGrammar(t *testing.T) {
},
Operator: "+",
Rhs: &DerefOrImm{
Immediate: ptrOf("5"),
Immediate: &ImmediateValue{
Sign: "",
Value: ptrOf("5"),
},
},
},
},
Expand All @@ -166,7 +172,10 @@ func TestCallAbsGrammar(t *testing.T) {
Call: &Call{
CallType: "abs",
Value: &DerefOrImm{
Immediate: ptrOf("123"),
Immediate: &ImmediateValue{
Sign: "",
Value: ptrOf("123"),
},
},
},
ApPlusOne: false,
Expand Down Expand Up @@ -245,6 +254,68 @@ func TestJumpGrammar(t *testing.T) {
}
}

func TestCallAbsGrammarNegativeImmediateGrammar(t *testing.T) {
code := "call abs -123;"

casmAst, err := parseCode(code)
require.NoError(t, err)

require.Equal(
t,
&CasmProgram{
[]InstructionNode{
{
Call: &Call{
CallType: "abs",
Value: &DerefOrImm{
Immediate: &ImmediateValue{
Sign: "-",
Value: ptrOf("123"),
},
},
},
ApPlusOne: false,
},
},
},
casmAst,
)
}

func TestAssertEqualWithNegativeImmediateGrammar(t *testing.T) {
code := "[fp + 1] = -5;"

casmAst, err := parseCode(code)
require.NoError(t, err)

require.Equal(
t,
&CasmProgram{
[]InstructionNode{
{
AssertEq: &AssertEq{
Dst: &Deref{
Name: "fp",
Offset: &Offset{
Sign: "+",
Value: ptrOf(1),
},
},
Value: &Expression{
Immediate: &ImmediateValue{
Sign: "-",
Value: ptrOf("5"),
},
},
},
ApPlusOne: false,
},
},
},
casmAst,
)
}

func ptrOf[T any](n T) *T {
return &n
}
Expand Down

0 comments on commit 1bfd306

Please sign in to comment.