public void ThrowOnUnknownExpressionType() { var m = new Module(null); var e = new UnknownExpression(); Assert.Throws <InvalidOperationException>(() => ConstantSolver.Solve(e, m.Block)); }
private TypeDefinition CheckArrayIndexSelector( IndexSelector indexSelector, TypeDefinition type) { if (!(type is ArrayTypeDefinition arrayType)) { _parser.NotifyErrorListeners(indexSelector.Token, "Array reference expected", null); return(SimpleTypeDefinition.VoidType); } indexSelector.IndexDefinition = ConstantSolver.Solve(indexSelector.IndexDefinition, _parser.currentBlock); if (indexSelector.IndexDefinition.TargetType.Type != BaseTypes.Int) { _parser.NotifyErrorListeners(indexSelector.Token, "Array reference must be INTEGER", null); return(SimpleTypeDefinition.VoidType); } if (indexSelector.IndexDefinition.IsConst) { var ce = (ConstantExpression)indexSelector.IndexDefinition; int index = ce.ToInt32(); if (index < 1 || index > arrayType.Size) { _parser.NotifyErrorListeners(indexSelector.Token, "Array index out of bounds", null); return(SimpleTypeDefinition.VoidType); } } return(arrayType.ArrayType); // types match }
public override void ExitConstDeclarationElement(OberonGrammarParser.ConstDeclarationElementContext context) { if (_parser.currentBlock.LookupVar(context.c.Text, false) != null) { _parser.NotifyErrorListeners( context.c, "A variable/constant with this name has been defined already", null); return; } if (!(ConstantSolver.Solve(context.e.expReturn, _parser.currentBlock) is ConstantExpression constantExpression)) { _parser.NotifyErrorListeners(context.e.start, "A constant must resolve during compile time", null); return; } var constDeclaration = new ConstDeclaration( context.c.Text, constantExpression.TargetType, constantExpression, _parser.currentBlock) { Exportable = context.export != null }; CheckExportable(context.export, constDeclaration.Exportable); _parser.currentBlock.Declarations.Add(constDeclaration); }
public void ExpressionNot() { var m = new Module(null); var e = BinaryExpression.Create(OberonGrammarLexer.NOT, new ConstantBoolExpression(true), null, m.Block); var result = ConstantSolver.Solve(e, m.Block) as ConstantBoolExpression; Assert.NotNull(result); Assert.False(result.ToBool()); }
public void ExpressionConstantStringReturnsIdentity() { const string test = "This is a test"; var m = new Module(null); var e = new StringExpression(test); var result = ConstantSolver.Solve(e, m.Block) as StringExpression; Assert.NotNull(result); Assert.True(result.IsConst); Assert.Equal(test, result.Value); }
public void ExpressionMult2() { var m = new Module(null); var e = BinaryExpression.Create( OberonGrammarLexer.STAR, ConstantExpression.Create(6.1), ConstantExpression.Create(7), m.Block); var result = ConstantSolver.Solve(e, m.Block) as ConstantDoubleExpression; Assert.NotNull(result); Assert.True(result.ToDouble() - 42.7 < double.Epsilon); }
public void ExpressionRelGe1() { var m = new Module(null); var e = BinaryExpression.Create( OberonGrammarLexer.GE, ConstantExpression.Create(4), ConstantExpression.Create(4), m.Block); var result = ConstantSolver.Solve(e, m.Block) as ConstantBoolExpression; Assert.NotNull(result); Assert.True(result.ToBool()); }
public void ExpressionDiv3() { var m = new Module(null); var e = BinaryExpression.Create( OberonGrammarLexer.DIV, ConstantExpression.Create("10.0"), ConstantExpression.Create(4), m.Block); var result = ConstantSolver.Solve(e, m.Block) as ConstantDoubleExpression; Assert.NotNull(result); Assert.Equal(2.5, result.ToDouble()); }
public void ExpressionDiv1() { var m = new Module(null); var e = BinaryExpression.Create( OberonGrammarLexer.DIV, ConstantExpression.Create(10), ConstantExpression.Create(2), m.Block); var result = ConstantSolver.Solve(e, m.Block) as ConstantIntExpression; Assert.NotNull(result); Assert.Equal(5, result.ToInt32()); }
public void ExpressionDiv0() { var m = new Module(null); var e = BinaryExpression.Create( OberonGrammarLexer.DIV, ConstantExpression.Create("10.0"), ConstantIntExpression.Zero, m.Block); var result = ConstantSolver.Solve(e, m.Block) as ConstantDoubleExpression; Assert.NotNull(result); Assert.True(double.IsInfinity(result.ToDouble())); }
public void ExpressionAnd() { var m = new Module(null); var e = BinaryExpression.Create( OberonGrammarLexer.AND, ConstantExpression.Create(false), ConstantExpression.Create("true"), m.Block); var result = ConstantSolver.Solve(e, m.Block) as ConstantBoolExpression; Assert.NotNull(result); Assert.False(result.ToBool()); }
public void ExpressionAdd2() { var m = new Module(null); var e = BinaryExpression.Create( OberonGrammarLexer.PLUS, ConstantExpression.Create(1), ConstantExpression.Create(1.42), m.Block); var result = ConstantSolver.Solve(e, m.Block) as ConstantDoubleExpression; Assert.NotNull(result); Assert.Equal(2.42, result.ToDouble()); }
public void ExpressionNot2() { var m = new Module(null); m.Block.Declarations.Add(new Declaration("a", m.Block.LookupType("BOOLEAN"))); var e = BinaryExpression.Create( OberonGrammarLexer.NOT, VariableReferenceExpression.Create(m.Block.LookupVar("a"), null), null, m.Block); var result = ConstantSolver.Solve(e, m.Block) as BinaryExpression; Assert.NotNull(result); }
public void ExpressionRelVar() { var m = new Module(null); m.Block.Declarations.Add(new Declaration("a", m.Block.LookupType("INTEGER"))); var e = BinaryExpression.Create( OberonGrammarLexer.NOTEQUAL, VariableReferenceExpression.Create(m.Block.LookupVar("a"), null), ConstantExpression.Create(10), m.Block); var result = ConstantSolver.Solve(e, m.Block) as BinaryExpression; Assert.NotNull(result); Assert.False(result.IsConst); }
public void ExpressionAddRes0() { var m = new Module(null); var e = BinaryExpression.Create( OberonGrammarLexer.PLUS, ConstantExpression.Create(1), ConstantDoubleExpression.Zero, m.Block); var result = ConstantSolver.Solve(e, m.Block) as ConstantDoubleExpression; Assert.NotNull(result); Assert.Equal(1, result.ToInt32()); Assert.Equal(1.0, result.ToDouble()); Assert.True(result.ToBool()); Assert.False(result.IsUnary); Assert.True(result.IsConst); }
public override void ExitArrayType(OberonGrammarParser.ArrayTypeContext context) { var constExpression = ConstantSolver.Solve(context.e.expReturn, _parser.currentBlock); if (constExpression is ConstantIntExpression cie) { context.returnType = new ArrayTypeDefinition(cie.ToInt32(), context.t.returnType); } else { _parser.NotifyErrorListeners( context.Start, "The array size must return a constant integer expression", null); context.returnType = new ArrayTypeDefinition(0, context.t.returnType); } }
public override void ExitAssign_statement(OberonGrammarParser.Assign_statementContext context) { var v = _parser.currentBlock.LookupVar(context.id.Text); if (v == null) { _parser.NotifyErrorListeners(context.id, $"Variable {context.id.Text} not known", null); return; } var targetType = v.Type; if (context.s.vsRet != null) { targetType = context.s.vsRet.SelectorResultType; } if (context.r?.expReturn == null) { _parser.NotifyErrorListeners(context.id, "Cannot parse right side of assignment", null); return; } var e = ConstantSolver.Solve(context.r.expReturn, _parser.currentBlock); if (!targetType.IsAssignable(e.TargetType)) { _parser.NotifyErrorListeners(context.id, "Left & right side do not match types", null); return; } _parser.currentBlock.Statements.Add( new AssignmentStatement { Variable = v, Selector = context.s.vsRet, Expression = e }); }
public void ConstantSolverNullInputExceptionForExpression() { Assert.Throws <ArgumentNullException>( () => ConstantSolver.Solve(null, new Block(null, new Module(null)))); }