protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); TargetType.CheckSemantics(astHelper); Expression.CheckSemantics(astHelper); }
/// <summary> /// Add the current function to the scope /// </summary> /// <param name = "astHelper"></param> public void AddToScope(AstHelper astHelper) { Name.CheckSemantics(astHelper); ReturnTypeName.CheckSemantics(astHelper); astHelper.Errors.Check(new SomeParametersWithTheSameNameError(Parameters, Start)); foreach (FunctionParameterExpression functionParameterExpression in Parameters) functionParameterExpression.CheckSemantics(astHelper); Type[] argTypes = Parameters.Select(param => param.Type).ToArray(); Type delegateType = ReturnTypeName.HasType ? MAst.GetFuncType(new List<Type>(argTypes) {Type}.ToArray()) : MAst.GetActionType(argTypes); Pointer = MAst.Parameter(delegateType); bool error = false; error |= astHelper.Errors.Check(new MemberWithSameSignatureAlreadyDefinedError( Name.Name, argTypes, astHelper, Name.Start)); error |= astHelper.Errors.Check(new VariableAlreadyDefinedError(Name.Name, astHelper, Start)); if (!error) astHelper.Functions.Add(Name.Name, new FunctionReference(Pointer, Type, argTypes)); }
protected internal override void CheckSemantics(AstHelper astHelper) { TypeName.CheckSemantics(astHelper); Name.CheckSemantics(astHelper); _parameter = MAst.Parameter(Type); }
protected internal override void CheckSemantics(AstHelper astHelper) { VariableName.CheckSemantics(astHelper); VariableTypeName.CheckSemantics(astHelper); AstHelper childScope = VariableTypeName.HasType ? astHelper.CreateChild(expecting: true, expectedType: VariableTypeName.ReferencedType) : astHelper.CreateChild(expecting: true); Value.CheckSemantics(childScope); bool cantInferType = astHelper.Errors.Check(new CanNotInferTypeError(Type, Value.Type, Start)); astHelper.Errors.Check(new NotAssignableError(Type, Value.Type, Start)); bool memberDeclared = astHelper.Errors.Check( new MemberWithSameNameAlreadyDefinedError(VariableName.Name, astHelper, Start)); if (!memberDeclared) { if (!cantInferType) { Pointer = MAst.Parameter(Type, VariableName.Name); } else { // if the type can't be inferred then register the variable with null type Pointer = MAst.Parameter(typeof (Null), VariableName.Name); } astHelper.Variables.Add(VariableName.Name, Pointer); } }
public static MAst Compile(AstHelper runtime, ICharStream stream) { var lexer = new TigerLexer(stream); var tokens = new CommonTokenStream(lexer); var parser = new TigerParser(tokens); ProgramExpression programExpression = parser.parse(); if (parser.NumberOfSyntaxErrors > 0) { IEnumerable<string> errors = from e in parser.Errors select e.ToString(); throw new SyntaxException(errors); } AstHelper helper = runtime.CreateChild(function: true, variables: true, types: true); programExpression.CheckSemantics(helper); if (helper.Errors.HasErrors) { throw new SemanticException(helper.Errors); } return programExpression.Transform(); }
protected internal override void CheckSemantics(AstHelper astHelper) { FunctionName.CheckSemantics(astHelper); // initialize the scopes for each one of the arguments var scopes = new AstHelper[Args.Count()]; for (int i = 0; i < scopes.Length; scopes[i++] = astHelper.CreateChild(expecting: true)) { } foreach (var item in Args.Zip(scopes, (arg, scope) => new {arg, scope})) item.arg.CheckSemantics(item.scope); Type[] argTypes = (from arg in Args select arg.Type).ToArray(); if (astHelper.Errors.Check(new FunctionNotDefinedError(FunctionName.Name, argTypes, astHelper.Functions, Start))) return; _pointer = astHelper.Functions[FunctionName.Name, argTypes]; // SPEC: The following are legal: function f(p:rec) = f(nil) // for that reason the expected type for each one of the arguments is the // type of the function argument (in the definition) foreach (var item in _pointer.ArgTypes.Zip(scopes, (type, scope) => new {type, scope})) item.scope.Expecting.Type = item.type; }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); foreach (Expression arg in Args) arg.CheckSemantics(astHelper); }
protected internal override void CheckSemantics(AstHelper astHelper) { Test.CheckSemantics(astHelper); Then.CheckSemantics(astHelper); astHelper.Errors.Check(new IfThenBodyReturnsValueError(Then.Type, Then.Start)); }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); // the identifier shouldn't be a keyword astHelper.Errors.Check(new IdentifierExpectedError(Name, Start)); }
protected internal override void CheckSemantics(AstHelper astHelper) { if (_checkSemanticsCalled) return; _checkSemanticsCalled = true; base.CheckSemantics(astHelper); Expression.CheckSemantics(astHelper); }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); Target.CheckSemantics(astHelper); foreach (Expression index in Indexes) index.CheckSemantics(astHelper); }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); AstHelper helper = astHelper.CreateChild(expecting: true, expectedType: typeof (bool)); _innerExpression.CheckSemantics(helper); // only void expressions can't be converted to bool astHelper.Errors.Check(new NotBoolConvertibleError(_innerExpression.Type, Start)); }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); Value.CheckSemantics(astHelper); // todo checkSemantics for the return expression class, similar to the continue/break with the assignments _returnLabel = astHelper.ReturnScope.ReturnLabel; }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); // if the type is not defined or is already a direct reference to it if (!HasType || ReferencedType != typeof (void)) return; if (!astHelper.Errors.Check(new MissingTypeError(TypeName, astHelper.Types, Start))) ReferencedType = astHelper.Types[TypeName]; }
public void AddToScope(AstHelper astHelper) { string typeName = astHelper.Types.Contains(Name.Name) ? Name.Name + TypeUniqueId++ : Name.Name; astHelper.Errors.Check(new TypeWithSameNameAlreadyDefinedError(Name.Name, astHelper.Types, Start)); _builder = astHelper.ModuleBuilder.DefineType(typeName, TypeAttributes.NotPublic); // the type is added to the scope with it's name astHelper.Types.Add(Name.Name, _builder); }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); FieldName.CheckSemantics(astHelper); var error = new FieldNotFoundError(Target.Type, FieldName.Name, Start); _type = !astHelper.Errors.Check(error) ? error.PropertyType : typeof (Null); }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); foreach (var item in Args.Zip(Constructor.GetParameters().Select(parameter => parameter.ParameterType), (arg, type) => new {arg, type})) { AstHelper helper = astHelper.CreateChild(expecting: true, expectedType: item.type); item.arg.CheckSemantics(helper); } }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); MethodName.CheckSemantics(astHelper); foreach (Expression expression in Args) expression.CheckSemantics(astHelper); Type[] argTypes = (from arg in Args select arg.Type).ToArray(); if (!astHelper.Errors.Check(new MethodNotFoundError(Target.Type, MethodName.Name, argTypes, Start))) _methodInfo = Target.Type.GetMethod(MethodName.Name, argTypes); }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); //Debug.Assert(!astHelper.Expecting.IsExpectingType,"A break is not allowed when we are expecting a type"); astHelper.Errors.Check(new ExpectingTypeError(Start, astHelper.Expecting)); if (! astHelper.Errors.Check(new BreakOutOfLoopScopeError(Start, astHelper.LoopScope))) { _target = astHelper.LoopScope.BreakLabel; } }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); Left.CheckSemantics(astHelper); Right.CheckSemantics(astHelper); // SPEC: Nil must be used in a context were its actual record type can be determined // SPEC: Thus the following are ilegal: var a := nil, if nil = nil then ... astHelper.Errors.Check(new CanNotInferTypeError(Left.Type, Right.Type, Start)); }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); Left.CheckSemantics(astHelper); AstHelper helper = astHelper.CreateChild(expecting: true, expectedType: Left.Type); Right.CheckSemantics(helper); astHelper.Errors.Check(new NotAssignableError(Left.Type, Right.Type, Start)); }
/// <summary> /// Comverts the expression into the corresponding /// <see cref="System.Linq.Expressions.Expression"/> /// </summary> /// <param name="runtime"></param> /// <returns></returns> /// <exception cref="SemanticException">if there is some semantic error in the tree</exception> public MAst Compile(AstHelper runtime) { AstHelper helper = runtime.CreateChild(function: true, variables: true, types: true); CheckSemantics(helper); if (helper.Errors.HasErrors) { throw new SemanticException(helper.Errors); } return Transform(); }
public void calls_function_in_runtime() { string program = "Calc()"; TigerParser parser = Mother.CreateParser(program); var runtime = new AstHelper(null); Expression<Func<int>> calc = () => 1; runtime.Functions.Add("Calc", new FunctionReference(calc, typeof (int))); Expression result = parser.parse().Compile(runtime); Mother.Test(result, 1); }
protected internal override void CheckSemantics(AstHelper astHelper) { foreach (RecordFieldNode fieldNode in Fields) { fieldNode.CheckSemantics(astHelper); if (fieldNode.TypeName.HasType) _builder.DefineField(fieldNode.FieldName.Name, fieldNode.TypeName.ReferencedType, FieldAttributes.Public); } astHelper.Types.CreateType(Name.Name); }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); ArrayTypeName.CheckSemantics(astHelper); // type must be an array: type XX = array of ... astHelper.Errors.Check(new NotAnArrayTypeError(Type, Start)); OriginalType = Type.GetElementType(); Lenght.CheckSemantics(astHelper); astHelper.Errors.Check(new TypeMismatchedError(Lenght.Type, typeof (int), Start)); }
protected internal override void CheckSemantics(AstHelper astHelper) { if (!astHelper.Errors.Check(new IdentifierNotDefinedError(VariableName, astHelper.Variables, Start))) { _pointer = astHelper.Variables[VariableName]; _type = _pointer.Type; } else { // if the variable isn't defined, apply the null type that can be assigned // to all the record types _type = astHelper.Expecting.IsExpectingType ? astHelper.Expecting.Type : typeof (Null); } }
protected internal override void CheckSemantics(AstHelper astHelper) { VariableName.CheckSemantics(astHelper); VariableTypeName.CheckSemantics(astHelper); bool memberDeclared = astHelper.Errors.Check(new MemberWithSameNameAlreadyDefinedError(VariableName.Name, astHelper, Start)); if (!memberDeclared) { Pointer = System.Linq.Expressions.Expression.Parameter(Type, VariableName.Name); astHelper.Variables.Add(VariableName.Name, Pointer); } }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); _breakLabel = MAst.Label(); _continueLabel = MAst.Label(); Test.CheckSemantics(astHelper); AstHelper child = astHelper.CreateChild(loop: true, breakLabel: _breakLabel, continueLabel: _continueLabel); Body.CheckSemantics(child); astHelper.Errors.Check(new WhileBodyReturnsValueError(Body.Type, Start)); }
protected internal override void CheckSemantics(AstHelper astHelper) { // SPEC: The comparison operators do not associate, e.g., a=b=c is erroneous, but a=(b=c) is legal. if (!Operator.IsComparison()) throw new InvalidOperationException(); AstHelper helper = astHelper.CreateChild(expecting: true); Left.CheckSemantics(helper); Right.CheckSemantics(helper); // SPEC: Nil must be used in a context were its actual record type can be determined // SPEC: Thus the following are ilegal: var a := nil, if nil = nil then ... astHelper.Errors.Check(new CanNotInferTypeError(Left.Type, Right.Type, Start)); astHelper.Errors.Check(new OperatorNotDefinedError(Left.Type, Right.Type, Operator, Start)); }
public static AstHelper Default(ModuleBuilder moduleBuilder) { var result = new AstHelper(moduleBuilder); result.Types.Add("int", typeof (int)); result.Types.Add("string", typeof (string)); result.Types.Add("bool", typeof (bool)); Expression<Func<int, string>> str = a => a.ToString(CultureInfo.InvariantCulture); result.Functions.Add("str", new FunctionReference(str, typeof (string), typeof (int))); // function ord(s : string) : int // Return the ASCII value of the first character of s, or €1 if s is empty. Expression<Func<string, int>> ord = a => string.IsNullOrEmpty(a) ? -1 : (int) a[0]; result.Functions.Add("ord", new FunctionReference(ord, typeof (int), typeof (string))); // function chr(i : int) : string // Return a single-character string for ASCII value i. Terminate program if i is out of range. // todo when chr is called terminate the program if i is out of range Expression<Func<int, string>> chr = a => ((char) a).ToString(); result.Functions.Add("chr", new FunctionReference(chr, typeof (string), typeof (int))); // function size(s : string) : int // Return the number of characters in s. Expression<Func<string, int>> size = a => a.Length; result.Functions.Add("size", new FunctionReference(size, typeof (int), typeof (string))); // function substring(s:string,f:int,n:int):string // Return the substring of s starting at the character f (first character is numbered zero) and going for n characters. Expression<Func<string, int, int, string>> substring = (s, f, n) => s.Substring(f, n); result.Functions.Add("substring", new FunctionReference(substring, typeof (int), typeof (string), typeof (int), typeof (int))); // function concat (s1:string, s2:string):string // Return a new string consisting of s1 followed by s2. Expression<Func<string, string, string>> concat = (s1, s2) => s1 + s2; result.Functions.Add("concat", new FunctionReference(concat, typeof (string), typeof (string), typeof (string))); // function not(i : int) : int // Return 1 if i is zero, 0 otherwise. Expression<Func<int, int>> not = i => i == 0 ? 1 : 0; result.Functions.Add("not", new FunctionReference(not, typeof (int), typeof (int))); return result; }
protected internal override void CheckSemantics(AstHelper astHelper) { // SPEC: The comparison operators do not associate, e.g., a=b=c is erroneous, but a=(b=c) is legal. if (!Operator.IsComparison()) { throw new InvalidOperationException(); } AstHelper helper = astHelper.CreateChild(expecting: true); Left.CheckSemantics(helper); Right.CheckSemantics(helper); // SPEC: Nil must be used in a context were its actual record type can be determined // SPEC: Thus the following are ilegal: var a := nil, if nil = nil then ... astHelper.Errors.Check(new CanNotInferTypeError(Left.Type, Right.Type, Start)); astHelper.Errors.Check(new OperatorNotDefinedError(Left.Type, Right.Type, Operator, Start)); }
protected internal override void CheckSemantics(AstHelper astHelper) { AstHelper helper = astHelper.CreateChild(function: true, variables: true, types: true); // add all type builders to the scope in case of recursive type calls foreach (IAddToScope typeDeclarationNode in TypeDeclarations.OfType <IAddToScope>()) { typeDeclarationNode.AddToScope(helper); } var error = new CircularTypeReferencesError(TypeDeclarations, Start); astHelper.Errors.Check(error); // define other types foreach (TypeDeclarationNode typeDeclarationNode in error.OrderedTypes) { typeDeclarationNode.CheckSemantics(helper); } // add all functions to the scope in case of recursive calls foreach (FunctionDefinitionExpression functionDefinitionExpression in FunctionDefinitions) { functionDefinitionExpression.AddToScope(helper); } foreach (VariableDeclarationBase variableDeclarationExpression in VariableDeclarations) { variableDeclarationExpression.CheckSemantics(helper); } foreach (FunctionDefinitionExpression functionDefinitionExpression in FunctionDefinitions) { functionDefinitionExpression.CheckSemantics(helper); } Body.CheckSemantics(helper); IEnumerable <ParameterExpression> variables = from variable in VariableDeclarations select variable.Pointer; IEnumerable <ParameterExpression> functions = from function in FunctionDefinitions select function.Pointer; // calculate the closure that will be used when we're generating the expression _closure = variables.Union(functions); }
protected internal override void CheckSemantics(AstHelper astHelper) { TypeName.CheckSemantics(astHelper); string result = "#result"; _inner = new LetInExpression { VariableDeclarations = new List <VariableDeclarationBase> { new VariableDeclarationExpression { VariableName = new MemberIdentifierNode { Name = result }, Value = new NewExpression(TypeName.ReferencedType) } }, Body = new ListSemiExpression(from field in Fields select new AssignExpression { Left = new FieldAccessExpression { FieldName = field.FieldName, Target = new VariableAccessExpression { VariableName = result } }, Right = field.Value, Start = field.Start }) { new VariableAccessExpression { VariableName = result } } }; _inner.CheckSemantics(astHelper); }
/// <summary> /// returns the expression that this program represents. /// </summary> /// <returns></returns> public MAst Compile() { var assemblyName = new AssemblyName(Guid.NewGuid().ToString()) { Version = new Version(1, 0) }; AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Program"); var ast = new AstHelper(moduleBuilder); ast.Types.Add("int", typeof(int)); ast.Types.Add("string", typeof(string)); ast.Types.Add("bool", typeof(bool)); Program.CheckSemantics(ast); return(Transform()); }
public AstHelper CreateChild(bool function = false, bool variables = false, bool types = false, bool expecting = false, Type expectedType = null, bool loop = false, LabelTarget breakLabel = null, LabelTarget continueLabel = null, bool returning = false, LabelTarget returnLabel = null) { var result = new AstHelper { ModuleBuilder = ModuleBuilder, Errors = Errors, Expecting = expecting ? expectedType != null ? new Expecting(expectedType) : new Expecting() : Expecting, Functions = function ? (FunctionScope)Functions.GetChild() : Functions, Variables = variables ? (VariableScope)Variables.GetChild() : Variables, Types = types ? (TypeScope)Types.GetChild() : Types, LoopScope = loop ? new LoopScope(breakLabel, continueLabel) : LoopScope, ReturnScope = returning ? new ReturnScope(returnLabel) : ReturnScope }; return(result); }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); astHelper.Errors.Check(new TypeWithSameNameAlreadyDefinedError(Name, astHelper.Types, Start)); }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); var from = From.ProtectSemantics(); var to = To.ProtectSemantics(); from.CheckSemantics(astHelper); to.CheckSemantics(astHelper); bool error = false; error |= astHelper.Errors.Check(new NotAssignableError(typeof(int), from.Type, VariableName.Start)); error |= astHelper.Errors.Check(new NotAssignableError(typeof(int), to.Type, VariableName.Start)); if (error) { return; } _implementation = new LetInExpression { VariableDeclarations = new List <VariableDeclarationBase> { new VariableDeclarationExpression { VariableName = new MemberIdentifierNode { Name = VariableName.Name }, Value = from } }, Body = new ListSemiExpression { new WhileExpression { Test = new LogicalBinaryOperationExpression { Left = new VariableAccessExpression { VariableName = VariableName.Name }, Right = to, Operator = TigerOperator.LessThanOrEqual }, Body = new ListSemiExpression { Body, new UnaryOperationExpression { Expression = new VariableAccessExpression { VariableName = VariableName.Name }, Operator = TigerOperator.PreIncrementAssign }, new EmptyExpression() } } } }; _implementation.CheckSemantics(astHelper); }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); var collectionWrapper = Collection.ProtectSemantics(); collectionWrapper.CheckSemantics(astHelper); if (!astHelper.Errors.Check(new NotEnumerableError(collectionWrapper.Type, Collection.Start))) { Type collectionType = TypeUtils.GetCollectionType(collectionWrapper.Type); string enumerator = "#enumerator" + _uniqueId++; _implementation = new LetInExpression { VariableDeclarations = new List <VariableDeclarationBase> { new VariableDeclarationExpression { VariableName = new MemberIdentifierNode { Name = enumerator }, Value = new MethodCallExpression { MethodName = new IdentifierNode { Name = "GetEnumerator" }, Target = collectionWrapper } }, new VariableDeclarationBase { VariableName = new MemberIdentifierNode { Name = Identifier.Name }, VariableTypeName = new TypeReferenceNode(collectionType) } }, Body = new ListSemiExpression { new WhileExpression { Test = new MethodCallExpression { Target = new VariableAccessExpression { VariableName = enumerator }, MethodName = new IdentifierNode { Name = "MoveNext" } }, Body = new ListSemiExpression { new AssignExpression { Left = new VariableAccessExpression { VariableName = Identifier.Name }, Right = new TypeCastExpression { Expression = new FieldAccessExpression { Target = new VariableAccessExpression { VariableName = enumerator }, FieldName = new IdentifierNode { Name = "Current" } }, TargetType = collectionType } }, Body } } } }; _implementation.CheckSemantics(astHelper); } }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); Expression.CheckSemantics(astHelper); }
protected internal override void CheckSemantics(AstHelper astHelper) { base.CheckSemantics(astHelper); _expecting = astHelper.Expecting; }
public static MAst Compile(AstHelper runtime, string program) { var stream = new ANTLRStringStream(program); return(Compile(runtime, stream)); }
public static MAst CompileFile(AstHelper runtime, string fileName) { var stream = new ANTLRFileStream(fileName); return(Compile(runtime, stream)); }
protected internal override void CheckSemantics(AstHelper astHelper) { Program.CheckSemantics(astHelper); }
public MAst Compile(AstHelper runtime) { Program.CheckSemantics(runtime); return(Transform()); }
protected internal override void CheckSemantics(AstHelper astHelper) { string lenght = "#length" + uniqueId++; string result = "#result" + uniqueId++; string forVarName = "#i" + uniqueId++; var valueEnclosed = InitialValue.ProtectSemantics(); _implementation = new LetInExpression { VariableDeclarations = new List <VariableDeclarationBase> { new VariableDeclarationExpression { VariableName = new MemberIdentifierNode { Name = lenght }, Value = Lenght }, new VariableDeclarationExpression { VariableName = new MemberIdentifierNode { Name = result }, Value = new ArrayInitializationExpression { ArrayTypeName = ArrayTypeName, Lenght = new VariableAccessExpression { VariableName = lenght } } } }, Body = new ListSemiExpression { new ForLoopExpression { VariableName = new IdentifierNode { Name = forVarName }, From = new IntLiteralExpression(0), To = new BinaryOperationExpression { Operator = TigerOperator.Subtract, Left = new VariableAccessExpression { VariableName = lenght }, Right = new IntLiteralExpression(1) }, Body = new AssignExpression { Left = new ArrayIndexExpression { Indexes = new[] { new VariableAccessExpression { VariableName = forVarName } }, Target = new VariableAccessExpression { VariableName = result } }, Right = valueEnclosed } }, new VariableAccessExpression { VariableName = result } } }; _implementation.CheckSemantics(astHelper); }
/// <summary> /// this method is executed before the generation, should /// resolve all variable references and populate the scopes. /// If some error is found the error should be added to the /// collection. /// </summary> /// <param name = "astHelper"></param> protected internal virtual void CheckSemantics(AstHelper astHelper) { // todo refactor the ModuleBuilder and the ErrorSet as parameters of CheckSemantic }