package core import ( "fmt" "git.akyoto.dev/cli/q/src/build/expression" ) // CompileCondition inserts code to jump to the start label or end label depending on the truth of the condition. func (f *Function) CompileCondition(condition *expression.Expression, successLabel string, failLabel string) error { switch condition.Token.Text() { case "||": f.count.subBranch++ leftFailLabel := fmt.Sprintf("%s_false_%d", f.Name, f.count.subBranch) // Left left := condition.Children[0] err := f.CompileCondition(left, successLabel, leftFailLabel) if err != nil { return err } f.JumpIfTrue(left.Token.Text(), successLabel) // Right f.AddLabel(leftFailLabel) right := condition.Children[1] err = f.CompileCondition(right, successLabel, failLabel) if condition.Parent != nil && condition.Parent.Token.Text() == "||" && condition != condition.Parent.LastChild() { f.JumpIfTrue(right.Token.Text(), successLabel) } else { f.JumpIfFalse(right.Token.Text(), failLabel) } return err case "&&": f.count.subBranch++ leftSuccessLabel := fmt.Sprintf("%s_true_%d", f.Name, f.count.subBranch) // Left left := condition.Children[0] err := f.CompileCondition(left, leftSuccessLabel, failLabel) if err != nil { return err } f.JumpIfFalse(left.Token.Text(), failLabel) // Right f.AddLabel(leftSuccessLabel) right := condition.Children[1] err = f.CompileCondition(right, successLabel, failLabel) if condition.Parent != nil && condition.Parent.Token.Text() == "||" && condition != condition.Parent.LastChild() { f.JumpIfTrue(right.Token.Text(), successLabel) } else { f.JumpIfFalse(right.Token.Text(), failLabel) } return err default: err := f.Compare(condition) if condition.Parent == nil { f.JumpIfFalse(condition.Token.Text(), failLabel) } return err } }