Logical or/and
This commit is contained in:
@@ -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")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -74,4 +74,6 @@ public enum Symbol
|
|||||||
LeftShift,
|
LeftShift,
|
||||||
RightShift,
|
RightShift,
|
||||||
Pipe,
|
Pipe,
|
||||||
|
And,
|
||||||
|
Or,
|
||||||
}
|
}
|
||||||
@@ -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,
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ public enum BinaryOperator
|
|||||||
GreaterThanOrEqual,
|
GreaterThanOrEqual,
|
||||||
LessThan,
|
LessThan,
|
||||||
LessThanOrEqual,
|
LessThanOrEqual,
|
||||||
|
LogicalAnd,
|
||||||
|
LogicalOr,
|
||||||
Plus,
|
Plus,
|
||||||
Minus,
|
Minus,
|
||||||
Multiply,
|
Multiply,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user