Skip to content

Commit

Permalink
binary and unary expressions check
Browse files Browse the repository at this point in the history
  • Loading branch information
Stepami committed Oct 16, 2023
1 parent 698fa64 commit c9c97a3
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Interpreter.Lib.BackEnd;
using Interpreter.Lib.IR.Ast.Visitors;
using Interpreter.Lib.IR.CheckSemantics.Visitors.SemanticChecker;

namespace Interpreter.Lib.IR.Ast.Impl.Nodes.Expressions;

Expand Down Expand Up @@ -28,6 +29,9 @@ public override IEnumerator<AbstractSyntaxTreeNode> GetEnumerator()

protected override string NodeRepresentation() => Operator;

public override Type Accept(SemanticChecker visitor) =>
visitor.Visit(this);

public override AddressedInstructions Accept(ExpressionInstructionProvider visitor) =>
visitor.Visit(this);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Interpreter.Lib.BackEnd;
using Interpreter.Lib.IR.Ast.Visitors;
using Interpreter.Lib.IR.CheckSemantics.Visitors.SemanticChecker;

namespace Interpreter.Lib.IR.Ast.Impl.Nodes.Expressions;

Expand All @@ -23,6 +24,9 @@ public override IEnumerator<AbstractSyntaxTreeNode> GetEnumerator()

protected override string NodeRepresentation() => Operator;

public override Type Accept(SemanticChecker visitor) =>
visitor.Visit(this);

public override AddressedInstructions Accept(ExpressionInstructionProvider visitor) =>
visitor.Visit(this);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ public class SemanticChecker :
IVisitor<IdentifierReference, Type>,
IVisitor<ImplicitLiteral, Type>,
IVisitor<ArrayLiteral, Type>,
IVisitor<ConditionalExpression, Type>
IVisitor<ConditionalExpression, Type>,
IVisitor<BinaryExpression, Type>,
IVisitor<UnaryExpression, Type>
{
private readonly IDefaultValueForTypeCalculator _calculator;

Expand Down Expand Up @@ -147,4 +149,60 @@ public Type Visit(ConditionalExpression visitable)
aSegment: visitable.Alternate.Segment,
aType);
}

public Type Visit(BinaryExpression visitable)
{
var lType = visitable.Left.Accept(this);
var rType = visitable.Right.Accept(this);

if (visitable.Operator != "::" && !lType.Equals(rType))
throw new IncompatibleTypesOfOperands(
visitable.Segment,
left: lType,
right: rType);

Type number = "number";
Type @string = "string";
Type boolean = "boolean";

return visitable.Operator switch
{
"+" when lType.Equals(number) => number,
"+" when lType.Equals(@string) => @string,
"+" => throw new UnsupportedOperation(visitable.Segment, lType, visitable.Operator),
"-" or "*" or "/" or "%" => lType.Equals(number)
? number
: throw new UnsupportedOperation(visitable.Segment, lType, visitable.Operator),
"||" or "&&" => lType.Equals(boolean)
? boolean
: throw new UnsupportedOperation(visitable.Segment, lType, visitable.Operator),
"==" or "!=" => boolean,
">" or ">=" or "<" or "<=" => lType.Equals(number)
? boolean
: throw new UnsupportedOperation(visitable.Segment, lType, visitable.Operator),
"++" => lType is ArrayType && rType is ArrayType
? lType
: throw new UnsupportedOperation(visitable.Segment, lType, visitable.Operator),
"::" when lType is not ArrayType => throw new UnsupportedOperation(visitable.Segment, lType,
visitable.Operator),
"::" => rType.Equals(number) ? "void" : throw new ArrayAccessException(visitable.Segment, rType),
_ => "undefined"
};
}

public Type Visit(UnaryExpression visitable)
{
var eType = visitable.Expression.Accept(this);

Type number = "number";
Type boolean = "boolean";

return visitable.Operator switch
{
"-" when eType.Equals(number) => number,
"!" when eType.Equals(boolean) => boolean,
"~" when eType is ArrayType => number,
_ => throw new UnsupportedOperation(visitable.Segment, eType, visitable.Operator)
};
}
}

0 comments on commit c9c97a3

Please sign in to comment.