mirror of
https://github.com/arnaucube/go-snark-study.git
synced 2026-02-02 17:26:41 +01:00
circuit parser (wip)
This commit is contained in:
@@ -1,10 +1,32 @@
|
||||
package circuitcompiler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
type Circuit struct {
|
||||
NVars int
|
||||
NPublic int
|
||||
NSignals int
|
||||
Inputs []int
|
||||
Witness []int
|
||||
Inputs []string
|
||||
Signals []string
|
||||
Witness []*big.Int
|
||||
Constraints []Constraint
|
||||
R1CS struct {
|
||||
A [][]*big.Int
|
||||
B [][]*big.Int
|
||||
C [][]*big.Int
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Circuit) GenerateR1CS() {
|
||||
fmt.Print("function with inputs: ")
|
||||
fmt.Println(c.Inputs)
|
||||
fmt.Print("signals: ")
|
||||
fmt.Println(c.Signals)
|
||||
for _, constraint := range c.Constraints {
|
||||
fmt.Println(constraint.Literal)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,16 +21,22 @@ func TestCircuitParser(t *testing.T) {
|
||||
m3 = m2 + s1
|
||||
out = m3 + 5
|
||||
*/
|
||||
raw := `
|
||||
y = x^x
|
||||
z = x + y
|
||||
out = z + 5
|
||||
`
|
||||
parser := NewParser(strings.NewReader(raw))
|
||||
res, err := parser.Parse()
|
||||
assert.Nil(t, err)
|
||||
fmt.Println(res)
|
||||
|
||||
// flat code
|
||||
flat := `
|
||||
func test(x):
|
||||
aux = x*x
|
||||
y = aux*x
|
||||
z = x + y
|
||||
out = z + 5
|
||||
`
|
||||
parser := NewParser(strings.NewReader(flat))
|
||||
circuit, err := parser.Parse()
|
||||
assert.Nil(t, err)
|
||||
fmt.Println(circuit)
|
||||
|
||||
// flat code to R1CS
|
||||
fmt.Println("generating R1CS from flat code")
|
||||
circuit.GenerateR1CS()
|
||||
fmt.Println(circuit.Inputs)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package circuitcompiler
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Parser struct {
|
||||
@@ -17,10 +19,12 @@ type Parser struct {
|
||||
type Constraint struct {
|
||||
// v1 op v2 = out
|
||||
Op Token
|
||||
V1 Token
|
||||
V2 Token
|
||||
Out Token
|
||||
V1 string
|
||||
V2 string
|
||||
Out string
|
||||
Literal string
|
||||
|
||||
Inputs []string // in func delcaration case
|
||||
}
|
||||
|
||||
func NewParser(r io.Reader) *Parser {
|
||||
@@ -57,36 +61,72 @@ func (p *Parser) ParseLine() (*Constraint, error) {
|
||||
in this version,
|
||||
line will be for example s3 = s1 * s4
|
||||
this is:
|
||||
val op val op val
|
||||
ident op ident op ident
|
||||
val eq val op val
|
||||
*/
|
||||
c := &Constraint{}
|
||||
var lit string
|
||||
c.Out, lit = p.scanIgnoreWhitespace()
|
||||
tok, lit := p.scanIgnoreWhitespace()
|
||||
c.Out = lit
|
||||
c.Literal += lit
|
||||
|
||||
if c.Literal == "func" {
|
||||
// format: `func name(in):`
|
||||
line, err := p.s.r.ReadString(':')
|
||||
if err != nil {
|
||||
return c, err
|
||||
}
|
||||
// read string inside ( )
|
||||
rgx := regexp.MustCompile(`\((.*?)\)`)
|
||||
insideParenthesis := rgx.FindStringSubmatch(line)
|
||||
varsString := strings.Replace(insideParenthesis[1], " ", "", -1)
|
||||
c.Inputs = strings.Split(varsString, ",")
|
||||
return c, nil
|
||||
}
|
||||
|
||||
_, lit = p.scanIgnoreWhitespace() // skip =
|
||||
c.Literal += lit
|
||||
c.V1, lit = p.scanIgnoreWhitespace()
|
||||
|
||||
// v1
|
||||
_, lit = p.scanIgnoreWhitespace()
|
||||
c.V1 = lit
|
||||
c.Literal += lit
|
||||
// operator
|
||||
c.Op, lit = p.scanIgnoreWhitespace()
|
||||
c.Literal += lit
|
||||
c.V2, lit = p.scanIgnoreWhitespace()
|
||||
// v2
|
||||
_, lit = p.scanIgnoreWhitespace()
|
||||
c.V2 = lit
|
||||
c.Literal += lit
|
||||
if c.Out == EOF {
|
||||
if tok == EOF {
|
||||
return nil, errors.New("eof in parseline")
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func addToArrayIfNotExist(arr []string, elem string) []string {
|
||||
for _, v := range arr {
|
||||
if v == elem {
|
||||
return arr
|
||||
}
|
||||
}
|
||||
arr = append(arr, elem)
|
||||
return arr
|
||||
}
|
||||
func (p *Parser) Parse() (*Circuit, error) {
|
||||
circuit := &Circuit{}
|
||||
circuit.Signals = append(circuit.Signals, "one")
|
||||
for {
|
||||
constraint, err := p.ParseLine()
|
||||
if err != nil {
|
||||
// return circuit, err
|
||||
break
|
||||
}
|
||||
if constraint.Literal == "func" {
|
||||
circuit.Inputs = constraint.Inputs
|
||||
continue
|
||||
}
|
||||
circuit.Constraints = append(circuit.Constraints, *constraint)
|
||||
circuit.Signals = addToArrayIfNotExist(circuit.Signals, constraint.V1)
|
||||
circuit.Signals = addToArrayIfNotExist(circuit.Signals, constraint.V2)
|
||||
circuit.Signals = addToArrayIfNotExist(circuit.Signals, constraint.Out)
|
||||
}
|
||||
return circuit, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user