Logical or/and

This commit is contained in:
nub31
2025-09-09 16:29:42 +02:00
parent e86571d1a2
commit aad41fbcbb
8 changed files with 45 additions and 21 deletions

View File

@@ -5,7 +5,7 @@ func main(args: []cstring): i64
{ {
let x: u32 = 23 let x: u32 = 23
if x == 23 && true if x == 11 || false
{ {
puts("yes") puts("yes")
} }

View File

@@ -725,13 +725,13 @@ public class QBEGenerator
var outputName = TmpName(); var outputName = TmpName();
var instruction = BinaryInstructionFor(binaryExpression.Operator, binaryExpression.Left.Type); var instruction = EmitBinaryInstructionForOperator(binaryExpression.Operator, binaryExpression.Left.Type);
_writer.Indented($"{outputName} {QBEAssign(binaryExpression.Left.Type)} {instruction} {left}, {right}"); _writer.Indented($"{outputName} {QBEAssign(binaryExpression.Left.Type)} {instruction} {left}, {right}");
return outputName; return outputName;
} }
private string BinaryInstructionFor(BinaryOperator op, TypeNode type) private static string EmitBinaryInstructionForOperator(BinaryOperator op, TypeNode type)
{ {
return op switch return op switch
{ {
@@ -881,6 +881,9 @@ public class QBEGenerator
}, },
_ => throw new NotSupportedException($"Greater than or equal comparison not supported for type '{type}'") _ => throw new NotSupportedException($"Greater than or equal comparison not supported for type '{type}'")
}, },
// todo(nub31): Implement short circuiting
BinaryOperator.LogicalAnd => "and",
BinaryOperator.LogicalOr => "or",
_ => throw new ArgumentOutOfRangeException(nameof(op)) _ => throw new ArgumentOutOfRangeException(nameof(op))
}; };
} }

View File

@@ -344,31 +344,34 @@ public sealed class Parser
return left; return left;
} }
private int GetBinaryOperatorPrecedence(BinaryOperatorSyntax operatorSyntax) private static int GetBinaryOperatorPrecedence(BinaryOperatorSyntax operatorSyntax)
{ {
return operatorSyntax switch return operatorSyntax switch
{ {
BinaryOperatorSyntax.Multiply => 6, BinaryOperatorSyntax.Multiply => 10,
BinaryOperatorSyntax.Divide => 6, BinaryOperatorSyntax.Divide => 10,
BinaryOperatorSyntax.Modulo => 6, BinaryOperatorSyntax.Modulo => 10,
BinaryOperatorSyntax.Plus => 5, BinaryOperatorSyntax.Plus => 9,
BinaryOperatorSyntax.Minus => 5, BinaryOperatorSyntax.Minus => 9,
BinaryOperatorSyntax.LeftShift => 4, BinaryOperatorSyntax.LeftShift => 8,
BinaryOperatorSyntax.RightShift => 4, BinaryOperatorSyntax.RightShift => 8,
BinaryOperatorSyntax.GreaterThan => 3, BinaryOperatorSyntax.GreaterThan => 7,
BinaryOperatorSyntax.GreaterThanOrEqual => 3, BinaryOperatorSyntax.GreaterThanOrEqual => 7,
BinaryOperatorSyntax.LessThan => 3, BinaryOperatorSyntax.LessThan => 7,
BinaryOperatorSyntax.LessThanOrEqual => 3, BinaryOperatorSyntax.LessThanOrEqual => 7,
BinaryOperatorSyntax.Equal => 2, BinaryOperatorSyntax.Equal => 7,
BinaryOperatorSyntax.NotEqual => 2, BinaryOperatorSyntax.NotEqual => 7,
BinaryOperatorSyntax.BitwiseAnd => 1, BinaryOperatorSyntax.BitwiseAnd => 6,
BinaryOperatorSyntax.BitwiseXor => 0, BinaryOperatorSyntax.BitwiseXor => 5,
BinaryOperatorSyntax.BitwiseOr => -1, BinaryOperatorSyntax.BitwiseOr => 4,
BinaryOperatorSyntax.LogicalAnd => 3,
BinaryOperatorSyntax.LogicalOr => 2,
_ => throw new ArgumentOutOfRangeException(nameof(operatorSyntax), operatorSyntax, null) _ => throw new ArgumentOutOfRangeException(nameof(operatorSyntax), operatorSyntax, null)
}; };
@@ -396,6 +399,12 @@ public sealed class Parser
case Symbol.GreaterThanOrEqual: case Symbol.GreaterThanOrEqual:
binaryExpressionOperator = BinaryOperatorSyntax.GreaterThanOrEqual; binaryExpressionOperator = BinaryOperatorSyntax.GreaterThanOrEqual;
return true; return true;
case Symbol.And:
binaryExpressionOperator = BinaryOperatorSyntax.LogicalAnd;
return true;
case Symbol.Or:
binaryExpressionOperator = BinaryOperatorSyntax.LogicalOr;
return true;
case Symbol.Plus: case Symbol.Plus:
binaryExpressionOperator = BinaryOperatorSyntax.Plus; binaryExpressionOperator = BinaryOperatorSyntax.Plus;
return true; return true;

View File

@@ -16,6 +16,8 @@ public enum BinaryOperatorSyntax
GreaterThanOrEqual, GreaterThanOrEqual,
LessThan, LessThan,
LessThanOrEqual, LessThanOrEqual,
LogicalAnd,
LogicalOr,
Plus, Plus,
Minus, Minus,
Multiply, Multiply,
@@ -25,7 +27,7 @@ public enum BinaryOperatorSyntax
RightShift, RightShift,
BitwiseAnd, BitwiseAnd,
BitwiseXor, BitwiseXor,
BitwiseOr BitwiseOr,
} }
public abstract record ExpressionSyntax(IEnumerable<Token> Tokens) : SyntaxNode(Tokens); public abstract record ExpressionSyntax(IEnumerable<Token> Tokens) : SyntaxNode(Tokens);

View File

@@ -74,4 +74,6 @@ public enum Symbol
LeftShift, LeftShift,
RightShift, RightShift,
Pipe, Pipe,
And,
Or,
} }

View File

@@ -30,6 +30,8 @@ public sealed class Tokenizer
[['>', '=']] = Symbol.GreaterThanOrEqual, [['>', '=']] = Symbol.GreaterThanOrEqual,
[['<', '<']] = Symbol.LeftShift, [['<', '<']] = Symbol.LeftShift,
[['>', '>']] = Symbol.RightShift, [['>', '>']] = Symbol.RightShift,
[['&', '&']] = Symbol.And,
[['|', '|']] = Symbol.Or,
[[':']] = Symbol.Colon, [[':']] = Symbol.Colon,
[['(']] = Symbol.OpenParen, [['(']] = Symbol.OpenParen,
[[')']] = Symbol.CloseParen, [[')']] = Symbol.CloseParen,

View File

@@ -16,6 +16,8 @@ public enum BinaryOperator
GreaterThanOrEqual, GreaterThanOrEqual,
LessThan, LessThan,
LessThanOrEqual, LessThanOrEqual,
LogicalAnd,
LogicalOr,
Plus, Plus,
Minus, Minus,
Multiply, Multiply,

View File

@@ -364,6 +364,8 @@ public sealed class TypeChecker
BinaryOperatorSyntax.BitwiseAnd => BinaryOperator.BitwiseAnd, BinaryOperatorSyntax.BitwiseAnd => BinaryOperator.BitwiseAnd,
BinaryOperatorSyntax.BitwiseXor => BinaryOperator.BitwiseXor, BinaryOperatorSyntax.BitwiseXor => BinaryOperator.BitwiseXor,
BinaryOperatorSyntax.BitwiseOr => BinaryOperator.BitwiseOr, BinaryOperatorSyntax.BitwiseOr => BinaryOperator.BitwiseOr,
BinaryOperatorSyntax.LogicalAnd => BinaryOperator.LogicalAnd,
BinaryOperatorSyntax.LogicalOr => BinaryOperator.LogicalOr,
_ => throw new ArgumentOutOfRangeException(nameof(expression.Operator), expression.Operator, null) _ => throw new ArgumentOutOfRangeException(nameof(expression.Operator), expression.Operator, null)
}; };
@@ -375,6 +377,8 @@ public sealed class TypeChecker
BinaryOperator.GreaterThanOrEqual => new BoolTypeNode(), BinaryOperator.GreaterThanOrEqual => new BoolTypeNode(),
BinaryOperator.LessThan => new BoolTypeNode(), BinaryOperator.LessThan => new BoolTypeNode(),
BinaryOperator.LessThanOrEqual => new BoolTypeNode(), BinaryOperator.LessThanOrEqual => new BoolTypeNode(),
BinaryOperator.LogicalAnd => new BoolTypeNode(),
BinaryOperator.LogicalOr => new BoolTypeNode(),
BinaryOperator.Plus => boundLeft.Type, BinaryOperator.Plus => boundLeft.Type,
BinaryOperator.Minus => boundLeft.Type, BinaryOperator.Minus => boundLeft.Type,
BinaryOperator.Multiply => boundLeft.Type, BinaryOperator.Multiply => boundLeft.Type,