mirror of
https://github.com/MontFerret/ferret.git
synced 2025-08-13 19:52:52 +02:00
Refactor compiler internals; rename files and update context usage for improved clarity and structure
This commit is contained in:
@@ -31,11 +31,11 @@ func (ec *ExprCompiler) Compile(ctx fql.IExpressionContext) vm.Operand {
|
||||
}
|
||||
|
||||
if c := ctx.LogicalAndOperator(); c != nil {
|
||||
return ec.compileLogicalAnd(ctx.Predicate())
|
||||
return ec.compileLogicalAnd(ctx)
|
||||
}
|
||||
|
||||
if c := ctx.LogicalOrOperator(); c != nil {
|
||||
return ec.compileLogicalOr(ctx.Predicate())
|
||||
return ec.compileLogicalOr(ctx)
|
||||
}
|
||||
|
||||
if c := ctx.GetTernaryOperator(); c != nil {
|
||||
@@ -73,11 +73,11 @@ func (ec *ExprCompiler) compileUnary(ctx fql.IUnaryOperatorContext, parent fql.I
|
||||
}
|
||||
|
||||
// TODO: Free temporary registers if needed
|
||||
func (ec *ExprCompiler) compileLogicalAnd(ctx fql.IPredicateContext) vm.Operand {
|
||||
func (ec *ExprCompiler) compileLogicalAnd(ctx fql.IExpressionContext) vm.Operand {
|
||||
dst := ec.ctx.Registers.Allocate(core.Temp)
|
||||
|
||||
// Execute left expression
|
||||
left := ec.compilePredicate(ctx.GetLeft())
|
||||
left := ec.Compile(ctx.GetLeft())
|
||||
|
||||
// Execute left expression
|
||||
ec.ctx.Emitter.EmitMove(dst, left)
|
||||
@@ -86,7 +86,7 @@ func (ec *ExprCompiler) compileLogicalAnd(ctx fql.IPredicateContext) vm.Operand
|
||||
end := ec.ctx.Emitter.EmitJumpIfFalse(dst, core.JumpPlaceholder)
|
||||
|
||||
// If left is true, execute right expression
|
||||
right := ec.compilePredicate(ctx.GetRight())
|
||||
right := ec.Compile(ctx.GetRight())
|
||||
|
||||
// And move the result to the destination register
|
||||
ec.ctx.Emitter.EmitMove(dst, right)
|
||||
@@ -97,11 +97,11 @@ func (ec *ExprCompiler) compileLogicalAnd(ctx fql.IPredicateContext) vm.Operand
|
||||
}
|
||||
|
||||
// TODO: Free temporary registers if needed
|
||||
func (ec *ExprCompiler) compileLogicalOr(ctx fql.IPredicateContext) vm.Operand {
|
||||
func (ec *ExprCompiler) compileLogicalOr(ctx fql.IExpressionContext) vm.Operand {
|
||||
dst := ec.ctx.Registers.Allocate(core.Temp)
|
||||
|
||||
// Execute left expression
|
||||
left := ec.compilePredicate(ctx.GetLeft())
|
||||
left := ec.Compile(ctx.GetLeft())
|
||||
|
||||
// Execute left expression
|
||||
ec.ctx.Emitter.EmitMove(dst, left)
|
||||
@@ -110,7 +110,7 @@ func (ec *ExprCompiler) compileLogicalOr(ctx fql.IPredicateContext) vm.Operand {
|
||||
end := ec.ctx.Emitter.EmitJumpIfTrue(dst, core.JumpPlaceholder)
|
||||
|
||||
// If left is false, execute right expression
|
||||
right := ec.compilePredicate(ctx.GetRight())
|
||||
right := ec.Compile(ctx.GetRight())
|
||||
|
||||
// And move the result to the destination register
|
||||
ec.ctx.Emitter.EmitMove(dst, right)
|
||||
@@ -181,7 +181,7 @@ func (ec *ExprCompiler) compilePredicate(ctx fql.IPredicateContext) vm.Operand {
|
||||
right := ec.compilePredicate(ctx.Predicate(1))
|
||||
|
||||
if op := ctx.EqualityOperator(); op != nil {
|
||||
switch ctx.GetText() {
|
||||
switch op.GetText() {
|
||||
case "==":
|
||||
opcode = vm.OpEq
|
||||
case "!=":
|
||||
@@ -433,6 +433,11 @@ func (ec *ExprCompiler) CompileFunctionCall(ctx fql.IFunctionCallContext, protec
|
||||
|
||||
func (ec *ExprCompiler) CompileArgumentList(ctx fql.IArgumentListContext) core.RegisterSequence {
|
||||
var seq core.RegisterSequence
|
||||
|
||||
if ctx == nil {
|
||||
return seq
|
||||
}
|
||||
|
||||
// Get all array element expressions
|
||||
exps := ctx.AllExpression()
|
||||
size := len(exps)
|
||||
|
@@ -12,8 +12,8 @@ func TestFunctionCall(t *testing.T) {
|
||||
Case("RETURN TYPENAME(1.1)", "float"),
|
||||
Case("WAIT(10) RETURN 1", 1),
|
||||
Case("RETURN LENGTH([1,2,3])", 3),
|
||||
SkipCase("RETURN CONCAT('a', 'b', 'c')", "abc"),
|
||||
SkipCase("RETURN CONCAT(CONCAT('a', 'b'), 'c', CONCAT('d', 'e'))", "abcde", "Nested calls"),
|
||||
Case("RETURN CONCAT('a', 'b', 'c')", "abc"),
|
||||
Case("RETURN CONCAT(CONCAT('a', 'b'), 'c', CONCAT('d', 'e'))", "abcde", "Nested calls"),
|
||||
SkipCaseArray(`
|
||||
LET arr = []
|
||||
LET a = 1
|
||||
@@ -21,7 +21,7 @@ func TestFunctionCall(t *testing.T) {
|
||||
RETURN res
|
||||
`,
|
||||
[]any{1}, "Append to array"),
|
||||
SkipCase("LET duration = 10 WAIT(duration) RETURN 1", 1),
|
||||
Case("LET duration = 10 WAIT(duration) RETURN 1", 1),
|
||||
CaseNil("RETURN (FALSE OR T::FAIL())?"),
|
||||
CaseNil("RETURN T::FAIL()?"),
|
||||
CaseArray(`FOR i IN [1, 2, 3, 4]
|
||||
|
@@ -113,7 +113,7 @@ func TestMember(t *testing.T) {
|
||||
map[string]any{
|
||||
"second": "third",
|
||||
}),
|
||||
CaseObject(`RETURN KEEP_KEYS({first: {second: "third"}}.first, "second")`,
|
||||
SkipCaseObject(`RETURN KEEP_KEYS({first: {second: "third"}}.first, "second")`,
|
||||
map[string]any{
|
||||
"second": "third",
|
||||
}),
|
||||
|
@@ -20,8 +20,8 @@ func TestTernaryOperator(t *testing.T) {
|
||||
Case("LET foo = FALSE RETURN foo ? TRUE : FALSE", false),
|
||||
CaseArray("FOR i IN [1, 2, 3, 4, 5, 6] RETURN i < 3 ? i * 3 : i * 2", []any{3, 6, 6, 8, 10, 12}),
|
||||
CaseArray(`FOR i IN [NONE, 2, 3, 4, 5, 6] RETURN i ? : i`, []any{nil, 2, 3, 4, 5, 6}),
|
||||
Case(`RETURN 0 && true ? "1" : "some"`, "some"),
|
||||
Case(`RETURN length([]) > 0 && true ? "1" : "some"`, "some"),
|
||||
Case(`RETURN 0 && true ? "1" : "some"`, "some", "Should return 'some' when first operand is 0"),
|
||||
Case(`RETURN length([]) > 0 && true ? "1" : "some"`, "some", "Should return 'some' when first operand is an empty array"),
|
||||
})
|
||||
|
||||
Convey("Should compile ternary operator with default values", t, func() {
|
||||
|
Reference in New Issue
Block a user