// Given a list of terms, create the variable objects to represent the parameters of the declaration private void CreateParameterDescriptors() { int parameterIndex = -3; if (HiddenArguments != null) { for (int i = HiddenArguments.Count - 1; i >= 0; --i) { if (Type != DeclarationType.System) { var hiddenArgument = new Variable(); hiddenArgument.StorageMethod = VariableStorageMethod.Local; hiddenArgument.Name = HiddenArguments[i].Item1; hiddenArgument.DeclaredTypeName = HiddenArguments[i].Item2; hiddenArgument.DeclaredType = DeclarationScope.FindType(hiddenArgument.DeclaredTypeName); if (hiddenArgument.DeclaredType == null) throw new CompileError("Could not find type for hidden argument '" + hiddenArgument.DeclaredTypeName + "'."); hiddenArgument.Offset = parameterIndex; DeclarationScope.Variables.Add(hiddenArgument); } --parameterIndex; } } for (int i = Terms.Count - 1; i >= 0; --i) { if (Terms[i].Type == DeclarationTermType.Term) { var declaredType = String.IsNullOrEmpty(Terms[i].DeclaredTypeName) ? EtcScriptLib.Type.Generic : DeclarationScope.FindType(Terms[i].DeclaredTypeName); if (declaredType == null) throw new CompileError("Could not find type '" + Terms[i].DeclaredTypeName + "'."); Terms[i].DeclaredType = declaredType; if (Type != DeclarationType.System) { var variable = new Variable { Name = Terms[i].Name, Offset = parameterIndex, DeclaredType = declaredType }; DeclarationScope.Variables.Add(variable); } --parameterIndex; } } }
public override Ast.Node Transform(ParseScope Scope) { List = List.Transform(Scope); ResultType = List.ResultType; //Try to find an access macro for this type. var getterArguments = DummyArguments(Keyword("GET"), Keyword("AT"), Term(Scope.FindType("NUMBER")), Keyword("FROM"), Term(List.ResultType)); var indexerMacro = Scope.FindAllPossibleMacroMatches(getterArguments).Where(d => ExactDummyMatch(d.Terms, getterArguments)).FirstOrDefault(); if (indexerMacro == null) throw new CompileError("No macro of the form GET AT NUMBER FROM " + List.ResultType.Name + " found.", Source); var lengthArguments = DummyArguments(Keyword("LENGTH"), Keyword("OF"), Term(List.ResultType)); var lengthMacro = Scope.FindAllPossibleMacroMatches(lengthArguments).Where(d => ExactDummyMatch(d.Terms, lengthArguments)).FirstOrDefault(); if (lengthMacro == null) throw new CompileError("No macro of the form LENGTH OF " + List.ResultType.Name + " found.", Source); var nestedScope = Scope.Push(ScopeType.Block); ResultVariable = nestedScope.NewLocal("__result@" + VariableName, Scope.FindType("LIST")); ListVariable = nestedScope.NewLocal("__list@" + VariableName, Scope.FindType("LIST")); TotalVariable = nestedScope.NewLocal("__total@" + VariableName, Scope.FindType("NUMBER")); CounterVariable = nestedScope.NewLocal("__counter@" + VariableName, Scope.FindType("NUMBER")); ValueVariable = nestedScope.NewLocal(VariableName, indexerMacro.ReturnType); Indexer = Ast.StaticInvokation.CreateCorrectInvokationNode(Source, nestedScope, indexerMacro, new List<Ast.Node>(new Ast.Node[] { new Ast.Identifier(new Token { Type = TokenType.Identifier, Value = "__counter@"+VariableName }), new Ast.Identifier(new Token { Type = TokenType.Identifier, Value = "__list@"+VariableName }) })).Transform(nestedScope); LengthFunc = Ast.StaticInvokation.CreateCorrectInvokationNode(Source, nestedScope, lengthMacro, new List<Ast.Node>(new Ast.Node[] { new Ast.Identifier(new Token { Type = TokenType.Identifier, Value = "__list@"+VariableName }) })).Transform(nestedScope); Condition = Condition.Transform(nestedScope); if (Condition.ResultType.Name != "BOOLEAN") throw new CompileError("Condition to where clause must return boolean", Source); return this; }
public Variable NewLocal(String Name, Type Type) { var r = new Variable { Name = Name.ToUpper(), Offset = VariableIndex, DeclaredType = Type }; VariableIndex += 1; Variables.Add(r); return r; }
internal static Variable ParseMemberDeclaration(TokenStream Stream, ParseContext Context) { if (Stream.Next().Type != TokenType.Identifier) throw new CompileError("[032] Expected identifier", Stream.Next()); Stream.Advance(); var r = new Variable(); r.StorageMethod = VariableStorageMethod.Member; if (Stream.Next().Type != TokenType.Identifier) throw new CompileError("[033] Expected identifier", Stream.Next()); r.Name = Stream.Next().Value.ToUpper(); Stream.Advance(); if (Stream.Next().Type == TokenType.Colon) { Stream.Advance(); if (Stream.Next().Type != TokenType.Identifier) throw new CompileError("[034] Expected identifier", Stream.Next()); r.DeclaredTypeName = Stream.Next().Value.ToUpper(); Stream.Advance(); } if (!Stream.AtEnd() && Stream.Next().Type == TokenType.QuestionMark) { Stream.Advance(); if (Stream.Next().Type != TokenType.String) throw new CompileError("Expected documentation", Stream); r.Documentation = Stream.Next().Value; Stream.Advance(); } if (Stream.Next().Type != TokenType.Semicolon) throw new CompileError("[035] Expected ;", Stream.Next()); Stream.Advance(); return r; }
internal static Variable ParseGlobalDeclaration(TokenStream Stream, ParseContext Context) { if (Stream.Next().Type != TokenType.Identifier) throw new CompileError("[032] Expected identifier", Stream.Next()); Stream.Advance(); var r = new Variable(); r.StorageMethod = VariableStorageMethod.Member; if (Stream.Next().Type != TokenType.Identifier) throw new CompileError("[033] Expected identifier", Stream.Next()); var start = Stream.Next(); r.Name = Stream.Next().Value.ToUpper(); Stream.Advance(); if (Stream.Next().Type == TokenType.Colon) { Stream.Advance(); if (Stream.Next().Type != TokenType.Identifier) throw new CompileError("[034] Expected identifier", Stream.Next()); r.DeclaredTypeName = Stream.Next().Value.ToUpper(); Stream.Advance(); } if (Stream.Next().Type == TokenType.Operator && Stream.Next().Value == "=") { Stream.Advance(); var initialValue = ParseExpression(Stream, Context, TokenType.Semicolon); var initializer = new Ast.Let(start, new Ast.Identifier(start), initialValue); Context.Initialization.Add(initializer); } if (!Stream.AtEnd() && Stream.Next().Type == TokenType.QuestionMark) { Stream.Advance(); if (Stream.Next().Type != TokenType.String) throw new CompileError("Expected documentation", Stream); r.Documentation = Stream.Next().Value; Stream.Advance(); } if (Stream.Next().Type != TokenType.Semicolon) throw new CompileError("[035] Expected ;", Stream.Next()); Stream.Advance(); return r; }
public override Ast.Node Transform(ParseScope Scope) { ResultType = Type.Void; Max = Max.Transform(Scope); var nestedScope = Scope.Push(ScopeType.Block); TotalVariable = nestedScope.NewLocal("__total@" + VariableName, Scope.FindType("NUMBER")); Min = Min.Transform(nestedScope); CounterVariable = nestedScope.NewLocal("__counter@" + VariableName, Scope.FindType("NUMBER")); ValueVariable = nestedScope.NewLocal(VariableName, Scope.FindType("NUMBER")); Body = Body.Transform(nestedScope); return this; }