Logical or/and
This commit is contained in:
@@ -5,7 +5,7 @@ func main(args: []cstring): i64
|
||||
{
|
||||
let x: u32 = 23
|
||||
|
||||
if x == 23 && true
|
||||
if x == 11 || false
|
||||
{
|
||||
puts("yes")
|
||||
}
|
||||
|
||||
@@ -725,13 +725,13 @@ public class QBEGenerator
|
||||
|
||||
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}");
|
||||
return outputName;
|
||||
}
|
||||
|
||||
private string BinaryInstructionFor(BinaryOperator op, TypeNode type)
|
||||
private static string EmitBinaryInstructionForOperator(BinaryOperator op, TypeNode type)
|
||||
{
|
||||
return op switch
|
||||
{
|
||||
@@ -881,6 +881,9 @@ public class QBEGenerator
|
||||
},
|
||||
_ => 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))
|
||||
};
|
||||
}
|
||||
|
||||
@@ -344,31 +344,34 @@ public sealed class Parser
|
||||
return left;
|
||||
}
|
||||
|
||||
private int GetBinaryOperatorPrecedence(BinaryOperatorSyntax operatorSyntax)
|
||||
private static int GetBinaryOperatorPrecedence(BinaryOperatorSyntax operatorSyntax)
|
||||
{
|
||||
return operatorSyntax switch
|
||||
{
|
||||
BinaryOperatorSyntax.Multiply => 6,
|
||||
BinaryOperatorSyntax.Divide => 6,
|
||||
BinaryOperatorSyntax.Modulo => 6,
|
||||
BinaryOperatorSyntax.Multiply => 10,
|
||||
BinaryOperatorSyntax.Divide => 10,
|
||||
BinaryOperatorSyntax.Modulo => 10,
|
||||
|
||||
BinaryOperatorSyntax.Plus => 5,
|
||||
BinaryOperatorSyntax.Minus => 5,
|
||||
BinaryOperatorSyntax.Plus => 9,
|
||||
BinaryOperatorSyntax.Minus => 9,
|
||||
|
||||
BinaryOperatorSyntax.LeftShift => 4,
|
||||
BinaryOperatorSyntax.RightShift => 4,
|
||||
BinaryOperatorSyntax.LeftShift => 8,
|
||||
BinaryOperatorSyntax.RightShift => 8,
|
||||
|
||||
BinaryOperatorSyntax.GreaterThan => 3,
|
||||
BinaryOperatorSyntax.GreaterThanOrEqual => 3,
|
||||
BinaryOperatorSyntax.LessThan => 3,
|
||||
BinaryOperatorSyntax.LessThanOrEqual => 3,
|
||||
BinaryOperatorSyntax.GreaterThan => 7,
|
||||
BinaryOperatorSyntax.GreaterThanOrEqual => 7,
|
||||
BinaryOperatorSyntax.LessThan => 7,
|
||||
BinaryOperatorSyntax.LessThanOrEqual => 7,
|
||||
|
||||
BinaryOperatorSyntax.Equal => 2,
|
||||
BinaryOperatorSyntax.NotEqual => 2,
|
||||
BinaryOperatorSyntax.Equal => 7,
|
||||
BinaryOperatorSyntax.NotEqual => 7,
|
||||
|
||||
BinaryOperatorSyntax.BitwiseAnd => 1,
|
||||
BinaryOperatorSyntax.BitwiseXor => 0,
|
||||
BinaryOperatorSyntax.BitwiseOr => -1,
|
||||
BinaryOperatorSyntax.BitwiseAnd => 6,
|
||||
BinaryOperatorSyntax.BitwiseXor => 5,
|
||||
BinaryOperatorSyntax.BitwiseOr => 4,
|
||||
|
||||
BinaryOperatorSyntax.LogicalAnd => 3,
|
||||
BinaryOperatorSyntax.LogicalOr => 2,
|
||||
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(operatorSyntax), operatorSyntax, null)
|
||||
};
|
||||
@@ -396,6 +399,12 @@ public sealed class Parser
|
||||
case Symbol.GreaterThanOrEqual:
|
||||
binaryExpressionOperator = BinaryOperatorSyntax.GreaterThanOrEqual;
|
||||
return true;
|
||||
case Symbol.And:
|
||||
binaryExpressionOperator = BinaryOperatorSyntax.LogicalAnd;
|
||||
return true;
|
||||
case Symbol.Or:
|
||||
binaryExpressionOperator = BinaryOperatorSyntax.LogicalOr;
|
||||
return true;
|
||||
case Symbol.Plus:
|
||||
binaryExpressionOperator = BinaryOperatorSyntax.Plus;
|
||||
return true;
|
||||
|
||||
@@ -16,6 +16,8 @@ public enum BinaryOperatorSyntax
|
||||
GreaterThanOrEqual,
|
||||
LessThan,
|
||||
LessThanOrEqual,
|
||||
LogicalAnd,
|
||||
LogicalOr,
|
||||
Plus,
|
||||
Minus,
|
||||
Multiply,
|
||||
@@ -25,7 +27,7 @@ public enum BinaryOperatorSyntax
|
||||
RightShift,
|
||||
BitwiseAnd,
|
||||
BitwiseXor,
|
||||
BitwiseOr
|
||||
BitwiseOr,
|
||||
}
|
||||
|
||||
public abstract record ExpressionSyntax(IEnumerable<Token> Tokens) : SyntaxNode(Tokens);
|
||||
|
||||
@@ -74,4 +74,6 @@ public enum Symbol
|
||||
LeftShift,
|
||||
RightShift,
|
||||
Pipe,
|
||||
And,
|
||||
Or,
|
||||
}
|
||||
@@ -30,6 +30,8 @@ public sealed class Tokenizer
|
||||
[['>', '=']] = Symbol.GreaterThanOrEqual,
|
||||
[['<', '<']] = Symbol.LeftShift,
|
||||
[['>', '>']] = Symbol.RightShift,
|
||||
[['&', '&']] = Symbol.And,
|
||||
[['|', '|']] = Symbol.Or,
|
||||
[[':']] = Symbol.Colon,
|
||||
[['(']] = Symbol.OpenParen,
|
||||
[[')']] = Symbol.CloseParen,
|
||||
|
||||
@@ -16,6 +16,8 @@ public enum BinaryOperator
|
||||
GreaterThanOrEqual,
|
||||
LessThan,
|
||||
LessThanOrEqual,
|
||||
LogicalAnd,
|
||||
LogicalOr,
|
||||
Plus,
|
||||
Minus,
|
||||
Multiply,
|
||||
|
||||
@@ -364,6 +364,8 @@ public sealed class TypeChecker
|
||||
BinaryOperatorSyntax.BitwiseAnd => BinaryOperator.BitwiseAnd,
|
||||
BinaryOperatorSyntax.BitwiseXor => BinaryOperator.BitwiseXor,
|
||||
BinaryOperatorSyntax.BitwiseOr => BinaryOperator.BitwiseOr,
|
||||
BinaryOperatorSyntax.LogicalAnd => BinaryOperator.LogicalAnd,
|
||||
BinaryOperatorSyntax.LogicalOr => BinaryOperator.LogicalOr,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(expression.Operator), expression.Operator, null)
|
||||
};
|
||||
|
||||
@@ -375,6 +377,8 @@ public sealed class TypeChecker
|
||||
BinaryOperator.GreaterThanOrEqual => new BoolTypeNode(),
|
||||
BinaryOperator.LessThan => new BoolTypeNode(),
|
||||
BinaryOperator.LessThanOrEqual => new BoolTypeNode(),
|
||||
BinaryOperator.LogicalAnd => new BoolTypeNode(),
|
||||
BinaryOperator.LogicalOr => new BoolTypeNode(),
|
||||
BinaryOperator.Plus => boundLeft.Type,
|
||||
BinaryOperator.Minus => boundLeft.Type,
|
||||
BinaryOperator.Multiply => boundLeft.Type,
|
||||
|
||||
Reference in New Issue
Block a user