Skip to content

Commit

Permalink
Implemented member expression
Browse files Browse the repository at this point in the history
  • Loading branch information
ziflex committed Oct 29, 2024
1 parent 0048d7b commit 66b14dc
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 164 deletions.
1 change: 1 addition & 0 deletions pkg/compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func (c *Compiler) Compile(query string) (program *runtime.Program, err error) {
program.Bytecode = l.emitter.instructions
program.Constants = l.symbols.constants
program.CatchTable = l.catchTable
program.Registers = int(l.registers.nextRegister)

return program, err
}
Expand Down
62 changes: 32 additions & 30 deletions pkg/compiler/compiler_setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,44 +77,46 @@ func ShouldHaveSameItems(actual any, expected ...any) string {

func RunUseCasesWith(t *testing.T, c *compiler.Compiler, useCases []UseCase, opts ...runtime.EnvironmentOption) {
for _, useCase := range useCases {
Convey(useCase.Expression, t, func() {
// catch panic
//defer func() {
// if r := recover(); r != nil {
// panic(fmt.Sprintf("%v,\nUse Case %d: - %s", r, idx+1, useCase.Expression))
// }
//}()
t.Run(useCase.Expression, func(t *testing.T) {
Convey(useCase.Expression, t, func() {
// catch panic
//defer func() {
// if r := recover(); r != nil {
// panic(fmt.Sprintf("%v,\nUse Case %d: - %s", r, idx+1, useCase.Expression))
// }
//}()

prog, err := c.Compile(useCase.Expression)
prog, err := c.Compile(useCase.Expression)

So(err, ShouldBeNil)
So(err, ShouldBeNil)

options := []runtime.EnvironmentOption{
runtime.WithFunctions(c.Functions().Unwrap()),
}
options = append(options, opts...)
options := []runtime.EnvironmentOption{
runtime.WithFunctions(c.Functions().Unwrap()),
}
options = append(options, opts...)

out, err := Exec(prog, ArePtrsEqual(useCase.Assertion, ShouldEqualJSON), options...)
out, err := Exec(prog, ArePtrsEqual(useCase.Assertion, ShouldEqualJSON), options...)

if !ArePtrsEqual(useCase.Assertion, ShouldBeError) {
So(err, ShouldBeNil)
}
if !ArePtrsEqual(useCase.Assertion, ShouldBeError) {
So(err, ShouldBeNil)
}

if ArePtrsEqual(useCase.Assertion, ShouldEqualJSON) {
expected, err := j.Marshal(useCase.Expected)
So(err, ShouldBeNil)
So(out, ShouldEqualJSON, string(expected))
} else if ArePtrsEqual(useCase.Assertion, ShouldBeError) {
if useCase.Expected != nil {
So(err, ShouldBeError, useCase.Expected)
if ArePtrsEqual(useCase.Assertion, ShouldEqualJSON) {
expected, err := j.Marshal(useCase.Expected)
So(err, ShouldBeNil)
So(out, ShouldEqualJSON, string(expected))
} else if ArePtrsEqual(useCase.Assertion, ShouldBeError) {
if useCase.Expected != nil {
So(err, ShouldBeError, useCase.Expected)
} else {
So(err, ShouldBeError)
}
} else if ArePtrsEqual(useCase.Assertion, ShouldHaveSameItems) {
So(out, ShouldHaveSameItems, useCase.Expected)
} else {
So(err, ShouldBeError)
So(out, ShouldEqual, useCase.Expected)
}
} else if ArePtrsEqual(useCase.Assertion, ShouldHaveSameItems) {
So(out, ShouldHaveSameItems, useCase.Expected)
} else {
So(out, ShouldEqual, useCase.Expected)
}
})
})
}
}
Expand Down
44 changes: 22 additions & 22 deletions pkg/compiler/compiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -758,17 +758,17 @@ func TestMember(t *testing.T) {
},
{
`LET o1 = {
first: {
second: {
["third"]: {
fourth: {
fifth: {
bottom: true
}
}
}
}
}
first: {
second: {
["third"]: {
fourth: {
fifth: {
bottom: true
}
}
}
}
}
}
LET o2 = { prop: "third" }
Expand All @@ -780,17 +780,17 @@ func TestMember(t *testing.T) {
},
{
`LET o1 = {
first: {
second: {
third: {
fourth: {
fifth: {
bottom: true
}
}
}
}
}
first: {
second: {
third: {
fourth: {
fifth: {
bottom: true
}
}
}
}
}
}
LET o2 = { prop: "third" }
Expand Down
109 changes: 48 additions & 61 deletions pkg/compiler/visitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,39 +400,49 @@ func (v *visitor) VisitFunctionCallExpression(ctx *fql.FunctionCallExpressionCon
}

func (v *visitor) VisitMemberExpression(ctx *fql.MemberExpressionContext) interface{} {
//src := ctx.MemberExpressionSource().(*fql.MemberExpressionSourceContext)
//
//if c := src.Variable(); c != nil {
// c.Accept(v)
//} else if c := src.Param(); c != nil {
// c.Accept(v)
//} else if c := src.ObjectLiteral(); c != nil {
// c.Accept(v)
//} else if c := src.ArrayLiteral(); c != nil {
// c.Accept(v)
//} else if c := src.FunctionCall(); c != nil {
// c.Accept(v)
//}
//
//segments := ctx.AllMemberExpressionPath()
//
//for _, segment := range segments {
// p := segment.(*fql.MemberExpressionPathContext)
//
// if c := p.PropertyName(); c != nil {
// c.Accept(v)
// } else if c := p.ComputedPropertyName(); c != nil {
// c.Accept(v)
// }
//
// if p.ErrorOperator() != nil {
// v.emitter.EmitABC(runtime.OpLoadPropertyOptional)
// } else {
// v.emitter.EmitABC(runtime.OpLoadProperty)
// }
//}
mes := ctx.MemberExpressionSource().(*fql.MemberExpressionSourceContext)

var mesOut interface{}

if c := mes.Variable(); c != nil {
mesOut = c.Accept(v)
} else if c := mes.Param(); c != nil {
mesOut = c.Accept(v)
} else if c := mes.ObjectLiteral(); c != nil {
mesOut = c.Accept(v)
} else if c := mes.ArrayLiteral(); c != nil {
mesOut = c.Accept(v)
} else if c := mes.FunctionCall(); c != nil {
mesOut = c.Accept(v)
}

var dst runtime.Operand
src1 := v.toRegister(mesOut.(runtime.Operand))
segments := ctx.AllMemberExpressionPath()

for _, segment := range segments {
var out2 interface{}
p := segment.(*fql.MemberExpressionPathContext)

if c := p.PropertyName(); c != nil {
out2 = c.Accept(v)
} else if c := p.ComputedPropertyName(); c != nil {
out2 = c.Accept(v)
}

return nil
src2 := v.toRegister(out2.(runtime.Operand))
dst = v.registers.Allocate(VarTemporary)

if p.ErrorOperator() != nil {
v.emitter.EmitABC(runtime.OpLoadPropertyOptional, dst, src1, src2)
} else {
v.emitter.EmitABC(runtime.OpLoadProperty, dst, src1, src2)
}

src1 = dst
}

return dst
}

func (v *visitor) VisitRangeOperator(ctx *fql.RangeOperatorContext) interface{} {
Expand Down Expand Up @@ -529,15 +539,15 @@ func (v *visitor) VisitArrayLiteral(ctx *fql.ArrayLiteralContext) interface{} {

// Free source register if temporary
if srcReg.IsRegister() {
v.registers.Free(srcReg)
//v.registers.Free(srcReg)
}
}

// Initialize an array
v.emitter.EmitAs(runtime.OpArray, destReg, seq)

// Free seq registers
v.registers.FreeSequence(seq)
//v.registers.FreeSequence(seq)

return destReg
}
Expand Down Expand Up @@ -594,7 +604,7 @@ func (v *visitor) VisitObjectLiteral(ctx *fql.ObjectLiteralContext) interface{}

// Free source register if temporary
if propOp.IsRegister() {
v.registers.Free(propOp)
//v.registers.Free(propOp)
}
}

Expand Down Expand Up @@ -817,7 +827,7 @@ func (v *visitor) VisitExpression(ctx *fql.ExpressionContext) interface{} {

// If condition was temporary, free it
if condReg.IsRegister() {
v.registers.Free(condReg)
//v.registers.Free(condReg)
}

// Jump to 'false' branch if condition is false
Expand All @@ -830,7 +840,7 @@ func (v *visitor) VisitExpression(ctx *fql.ExpressionContext) interface{} {

// Free temporary register if needed
if trueReg.IsRegister() {
v.registers.Free(trueReg)
//v.registers.Free(trueReg)
}
}

Expand All @@ -845,7 +855,7 @@ func (v *visitor) VisitExpression(ctx *fql.ExpressionContext) interface{} {

// Free temporary register if needed
if falseReg.IsRegister() {
v.registers.Free(falseReg)
//v.registers.Free(falseReg)
}
}

Expand Down Expand Up @@ -999,26 +1009,3 @@ func (v *visitor) toRegister(op runtime.Operand) runtime.Operand {

return reg
}

func (v *visitor) endLoopScope() {
//v.loops = v.loops[:len(v.loops)-1]
//
//var unwrap bool
//
//if len(v.loops) == 0 {
// unwrap = true
//} else if !v.loops[len(v.loops)-1].passThrough {
// unwrap = true
//}
//
//if unwrap {
// v.emitter.EmitABC(runtime.OpLoopUnwrapOutput)
//}
}

// emitLoop emits a loop instruction.
func (v *visitor) emitLoop(loopStart int) {
//pos := v.emitJump(runtime.OpJumpBackward)
//jump := pos - loopStart
//v.arguments[pos-1] = jump
}
1 change: 1 addition & 0 deletions pkg/runtime/program.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type Program struct {
Bytecode []Instruction
Constants []core.Value
CatchTable [][2]int
Registers int
}

func (program *Program) Disassemble() string {
Expand Down
Loading

0 comments on commit 66b14dc

Please sign in to comment.