1
0
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:
Tim Voronov
2025-06-11 10:28:09 -04:00
parent 775e24b5b2
commit b0158406da
4 changed files with 20 additions and 15 deletions

View File

@@ -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)

View File

@@ -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]

View File

@@ -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",
}),

View File

@@ -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() {