Skip to content

Commit

Permalink
Empty array
Browse files Browse the repository at this point in the history
  • Loading branch information
ziflex committed Oct 26, 2024
1 parent c2c11c4 commit 231fde0
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 50 deletions.
2 changes: 1 addition & 1 deletion pkg/compiler/allocator.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type (
func NewRegisterAllocator() *RegisterAllocator {
return &RegisterAllocator{
registers: make(map[runtime.Operand]*RegisterStatus),
nextRegister: 0,
nextRegister: runtime.ResultOperand + 1, // we start at 1 to avoid ResultOperand
lifetimes: make(map[string]*RegisterLifetime),
usageGraph: make(map[runtime.Operand]map[runtime.Operand]bool),
}
Expand Down
50 changes: 25 additions & 25 deletions pkg/compiler/compiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,31 @@ func TestVariables(t *testing.T) {
nil,
nil,
},
//{
// `LET a = TRUE RETURN a`,
// true,
// nil,
//},
//{
// `LET a = 1 RETURN a`,
// 1,
// nil,
//},
//{
// `LET a = 1.1 RETURN a`,
// 1.1,
// nil,
//},
//{
// `LET i = 'foo' RETURN i`,
// "foo",
// nil,
//},
//{
// `LET i = [] RETURN i`,
// []any{},
// ShouldEqualJSON,
//},
{
`LET a = TRUE RETURN a`,
true,
nil,
},
{
`LET a = 1 RETURN a`,
1,
nil,
},
{
`LET a = 1.1 RETURN a`,
1.1,
nil,
},
{
`LET i = 'foo' RETURN i`,
"foo",
nil,
},
{
`LET i = [] RETURN i`,
[]any{},
ShouldEqualJSON,
},
//{
// `LET i = [1, 2, 3] RETURN i`,
// []any{1, 2, 3},
Expand Down
5 changes: 5 additions & 0 deletions pkg/compiler/emitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ func (e *Emitter) EmitAB(op runtime.Opcode, dest, src1 runtime.Operand) {
e.EmitABC(op, dest, src1, 0)
}

// EmitABx emits an opcode with a destination register and a custom argument.
func (e *Emitter) EmitABx(op runtime.Opcode, dest runtime.Operand, arg int) {
e.EmitABC(op, dest, runtime.Operand(arg), 0)
}

// EmitABC emits an opcode with a destination register and two source register arguments.
func (e *Emitter) EmitABC(op runtime.Opcode, dest, src1, src2 runtime.Operand) {
e.instructions = append(e.instructions, runtime.Instruction{
Expand Down
19 changes: 8 additions & 11 deletions pkg/compiler/symbols.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
type SymbolTable struct {
constants []core.Value
constantsIndex map[uint64]int
globals map[string]int
globals map[string]runtime.Operand
scope int
locals []Variable
registers *RegisterAllocator
Expand All @@ -19,7 +19,7 @@ func NewSymbolTable(registers *RegisterAllocator) *SymbolTable {
return &SymbolTable{
constants: make([]core.Value, 0),
constantsIndex: make(map[uint64]int),
globals: make(map[string]int),
globals: make(map[string]runtime.Operand),
locals: make([]Variable, 0),
registers: registers,
}
Expand Down Expand Up @@ -62,8 +62,6 @@ func (st *SymbolTable) AddConstant(constant core.Value) runtime.Operand {
}

func (st *SymbolTable) DefineVariable(name string) runtime.Operand {
var index int

if st.scope == 0 {
// Check for duplicate global variable names.
_, ok := st.globals[name]
Expand All @@ -72,12 +70,11 @@ func (st *SymbolTable) DefineVariable(name string) runtime.Operand {
panic(core.Error(ErrVariableNotUnique, name))
}

index = len(st.globals)
op := st.AddConstant(values.NewString(name))
// Define global variable.
st.globals[name] = index
st.globals[name] = op

// Return a constant operand to indicate that this is a global variable and use its index.
return st.AddConstant(values.NewString(name))
return op
}

register := st.registers.AllocateLocalVar(name)
Expand All @@ -88,7 +85,7 @@ func (st *SymbolTable) DefineVariable(name string) runtime.Operand {
Register: register,
})

return runtime.NewRegisterOperand(index)
return register
}

func (st *SymbolTable) LookupVariable(name string) runtime.Operand {
Expand All @@ -99,13 +96,13 @@ func (st *SymbolTable) LookupVariable(name string) runtime.Operand {
}
}

index, ok := st.globals[name]
op, ok := st.globals[name]

if !ok {
panic(core.Error(ErrVariableNotFound, name))
}

return runtime.NewConstantOperand(index)
return op
}

func (st *SymbolTable) ExitScope() {
Expand Down
30 changes: 20 additions & 10 deletions pkg/compiler/visitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,16 +491,21 @@ func (v *visitor) VisitVariable(ctx *fql.VariableContext) interface{} {
}

func (v *visitor) VisitArrayLiteral(ctx *fql.ArrayLiteralContext) interface{} {
//var size int
//
//if args := ctx.ArgumentList(); args != nil {
// out := v.VisitArgumentList(args.(*fql.ArgumentListContext))
// size = out.(int)
//}
//
//v.emitter.EmitABC(runtime.OpArray, size)
dest := v.registers.Allocate(VarTemporary)
var size int

return nil
if args := ctx.ArgumentList(); args != nil {
exps := args.AllExpression()
size = len(exps)

//for _, arg := range exps {
// arg.Accept(v)
//}
}

v.emitter.EmitABx(runtime.OpArray, dest, size)

return dest
}

func (v *visitor) VisitArgumentList(ctx *fql.ArgumentListContext) interface{} {
Expand Down Expand Up @@ -664,7 +669,12 @@ func (v *visitor) VisitLiteral(ctx *fql.LiteralContext) interface{} {
func (v *visitor) VisitReturnExpression(ctx *fql.ReturnExpressionContext) interface{} {
valReg := ctx.Expression().Accept(v).(runtime.Operand)

v.emitter.EmitAB(runtime.OpMove, runtime.ResultOperand, valReg)
if valReg.IsConstant() {
v.emitter.EmitAB(runtime.OpLoadGlobal, runtime.ResultOperand, valReg)
} else {
v.emitter.EmitAB(runtime.OpMove, runtime.ResultOperand, valReg)
}

v.emitter.Emit(runtime.OpReturn)

//if len(v.loops) == 0 {
Expand Down
2 changes: 2 additions & 0 deletions pkg/runtime/opcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const (
OpDecr

OpArray
OpStoreIndex

OpObject
OpLoadProperty
OpLoadPropertyOptional
Expand Down
7 changes: 4 additions & 3 deletions pkg/runtime/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/operators"
"github.com/MontFerret/ferret/pkg/runtime/values"
)

type VM struct {
Expand Down Expand Up @@ -55,7 +56,7 @@ loop:
case OpStoreGlobal:
vm.globals[program.Constants[dst.Constant()].String()] = vm.load(src1)
case OpLoadGlobal:
reg[dst] = vm.globals[program.Constants[src1].String()]
reg[dst] = vm.globals[program.Constants[src1.Constant()].String()]
case OpAdd:
reg[dst] = operators.Add(vm.load(src1), vm.load(src2))
case OpSub:
Expand All @@ -75,8 +76,7 @@ loop:
//stack.Push(values.ToBoolean(stack.Pop()))

case OpArray:
//size := arg
//arr := values.NewSizedArray(size)
arr := values.NewSizedArray(int(src1))
//
//// iterate from the end to the beginning
//// because stack is LIFO
Expand All @@ -85,6 +85,7 @@ loop:
//}
//
//stack.Push(arr)
reg[dst] = arr

case OpObject:
//obj := values.NewObject()
Expand Down

0 comments on commit 231fde0

Please sign in to comment.