package core import ( "git.urbach.dev/cli/q/src/expression" "git.urbach.dev/cli/q/src/token" ) // 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.Kind { case token.LogicalOr: f.count.subBranch++ leftFailLabel := f.CreateLabel("false", f.count.subBranch) // Left left := condition.Children[0] err := f.CompileCondition(left, successLabel, leftFailLabel) if err != nil { return err } f.JumpIfTrue(left.Token.Kind, successLabel) // Right f.AddLabel(leftFailLabel) right := condition.Children[1] err = f.CompileCondition(right, successLabel, failLabel) if condition.Parent != nil && condition.Parent.Token.Kind == token.LogicalOr && condition != condition.Parent.LastChild() { f.JumpIfTrue(right.Token.Kind, successLabel) } else { f.JumpIfFalse(right.Token.Kind, failLabel) } return err case token.LogicalAnd: f.count.subBranch++ leftSuccessLabel := f.CreateLabel("true", f.count.subBranch) // Left left := condition.Children[0] err := f.CompileCondition(left, leftSuccessLabel, failLabel) if err != nil { return err } f.JumpIfFalse(left.Token.Kind, failLabel) // Right f.AddLabel(leftSuccessLabel) right := condition.Children[1] err = f.CompileCondition(right, successLabel, failLabel) if condition.Parent != nil && condition.Parent.Token.Kind == token.LogicalOr && condition != condition.Parent.LastChild() { f.JumpIfTrue(right.Token.Kind, successLabel) } else { f.JumpIfFalse(right.Token.Kind, failLabel) } return err default: err := f.Compare(condition) if condition.Parent == nil { f.JumpIfFalse(condition.Token.Kind, failLabel) } return err } }