From f2ce462a233ceca23d05617349a3f765563f2f42 Mon Sep 17 00:00:00 2001 From: toxamin <30242831+toxamin@users.noreply.github.com> Date: Mon, 17 Nov 2025 20:51:30 +0200 Subject: [PATCH] Add if expression support to the compiler --- src/prometheus/compiler/compiler.lua | 58 ++++++++++++++++++++++++++++ src/prometheus/visitast.lua | 4 +- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/prometheus/compiler/compiler.lua b/src/prometheus/compiler/compiler.lua index a3c714e..72f4ed0 100644 --- a/src/prometheus/compiler/compiler.lua +++ b/src/prometheus/compiler/compiler.lua @@ -2359,6 +2359,64 @@ function Compiler:compileExpression(expression, funcDepth, numReturns) return regs; end + if(expression.kind == AstKind.IfElseExpression) then + local posState = self.registers[self.POS_REGISTER]; + self.registers[self.POS_REGISTER] = self.VAR_REGISTER; + + local regs = {}; + for i=1, numReturns do + regs[i] = self:allocRegister(); + if(i ~= 1) then + self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false); + end + end + + local resReg = regs[1]; + local tmpReg; + + if posState then + tmpReg = self:allocRegister(false); + self:addStatement(self:copyRegisters(scope, {tmpReg}, {self.POS_REGISTER}), {tmpReg}, {self.POS_REGISTER}, false); + end + + local conditionReg = self:compileExpression(expression.condition, funcDepth, 1)[1]; + + local trueBlock, falseBlock, finalBlock = self:createBlock(), self:createBlock(), self:createBlock(); + + self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.OrExpression(Ast.AndExpression(self:register(scope, conditionReg), Ast.NumberExpression(trueBlock.id)), Ast.NumberExpression(falseBlock.id))), {self.POS_REGISTER}, {conditionReg}, false); + self:freeRegister(conditionReg, false); + + do + self:setActiveBlock(trueBlock); + local scope = trueBlock.scope; + local trueReg = self:compileExpression(expression.true_value, funcDepth, 1)[1]; + self:addStatement(self:copyRegisters(scope, {resReg}, {trueReg}), {resReg}, {trueReg}, false); + self:freeRegister(trueReg, false); + self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.NumberExpression(finalBlock.id)), {self.POS_REGISTER}, {}, false); + end + + do + self:setActiveBlock(falseBlock); + local scope = falseBlock.scope; + local falseReg = self:compileExpression(expression.false_value, funcDepth, 1)[1]; + self:addStatement(self:copyRegisters(scope, {resReg}, {falseReg}), {resReg}, {falseReg}, false); + self:freeRegister(falseReg, false); + self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.NumberExpression(finalBlock.id)), {self.POS_REGISTER}, {}, false); + end + + self.registers[self.POS_REGISTER] = posState; + + self:setActiveBlock(finalBlock); + scope = finalBlock.scope; + + if tmpReg then + self:addStatement(self:copyRegisters(scope, {self.POS_REGISTER}, {tmpReg}), {self.POS_REGISTER}, {tmpReg}, false); + self:freeRegister(tmpReg, false); + end + + return regs; + end + logger:error(string.format("%s is not an compliable expression!", expression.kind)); end diff --git a/src/prometheus/visitast.lua b/src/prometheus/visitast.lua index 847bf49..a736eba 100644 --- a/src/prometheus/visitast.lua +++ b/src/prometheus/visitast.lua @@ -237,8 +237,8 @@ function visitExpression(expression, previsit, postvisit, data) end if(expression.kind == AstKind.IfElseExpression) then expression.condition = visitExpression(expression.condition, previsit, postvisit, data); - expression.true_expr = visitExpression(expression.true_expr, previsit, postvisit, data); - expression.false_expr = visitExpression(expression.false_expr, previsit, postvisit, data); + expression.true_value = visitExpression(expression.true_value, previsit, postvisit, data); + expression.false_value = visitExpression(expression.false_value, previsit, postvisit, data); end if(type(postvisit) == "function") then