private static void ResolveReturns(bool hasReturnType, BlockLexeme parent, out CompileError error) { error = null; if (parent == null) { return; } foreach (var lexeme in parent.ChildLexemes) { if (lexeme.Type == LexemeType.Return && !hasReturnType) { error = new CompileError(CompileErrorType.ReturnInVoidFunction, lexeme.Tokens[0]); return; } if (lexeme.RequireBlock) { ResolveReturns(hasReturnType, ((ComplexLexeme)lexeme).Block, out error); if (error != null) { return; } } if (lexeme.Type == LexemeType.Block) { ResolveReturns(hasReturnType, (BlockLexeme)lexeme, out error); if (error != null) { return; } } } }
private static void ClearEmptyLexemes(BlockLexeme root) { var toDelete = new List <int>(); int index = 0; foreach (var lexeme in root.ChildLexemes) { if (lexeme.Type == LexemeType.Block) { ClearEmptyLexemes((BlockLexeme)lexeme); } else { if (lexeme.Tokens.Count == 0) { toDelete.Add(index); } } index++; } toDelete.Reverse(); foreach (var ind in toDelete) { root.ChildLexemes.RemoveAt(ind); } }
private static BlockLexeme GetStructureLexeme(List <Token> tokens, out CompileError error) { error = null; var iterator = new TokenIterator <Token>(tokens); var possibleLexeme = new List <Token>(); var currentParent = new BlockLexeme(null, -1); int level = 0; Token lastClosed = null; while (iterator.GetNext() != null) { if (iterator.Current.Type == TokenType.Semicolon || iterator.Current.Type == TokenType.BraceOpened || iterator.Current.Type == TokenType.BraceClosed) { currentParent.ChildLexemes.Add(new UnknownLexeme(possibleLexeme)); possibleLexeme.Clear(); switch (iterator.Current.Type) { case TokenType.BraceOpened: var oldParent = currentParent; currentParent = new BlockLexeme(oldParent, iterator.Index); oldParent.ChildLexemes.Add(currentParent); level++; break; case TokenType.BraceClosed: currentParent = (BlockLexeme)currentParent.Parent; lastClosed = iterator.Current; level--; break; } } else { possibleLexeme.Add(iterator.Current); } } if (possibleLexeme.Count != 0) { currentParent.ChildLexemes.Add(new UnknownLexeme(possibleLexeme)); } if (level != 0) { error = new CompileError(CompileErrorType.WrongCodeStructure, lastClosed); } return(currentParent); }
private static bool HasInStack(BlockLexeme parent, int scope) { while (parent.Parent != null) { if (parent.Scope == scope) { return(true); } parent = (BlockLexeme)parent.Parent; } return(false); }
private static void LinkBlocksToLexemes(BlockLexeme root, out CompileError error, bool prototypesOnly) { var toDelete = new List <int>(); int index = 0; error = null; foreach (var lexeme in root.ChildLexemes) { if (lexeme == null) { toDelete.Add(index); } else { if (lexeme.Type == LexemeType.Block) { var bl = (BlockLexeme)lexeme; var prev = index > 0 ? root.ChildLexemes[index - 1] : null; if (prev != null && prev.RequireBlock) { toDelete.Add(index); ((ComplexLexeme)prev).Block = bl; } LinkBlocksToLexemes((BlockLexeme)lexeme, out error, prototypesOnly); if (error != null) { return; } } } index++; } toDelete.Reverse(); foreach (var ind in toDelete) { root.ChildLexemes.RemoveAt(ind); } foreach (var lexeme in root.ChildLexemes) { if (!prototypesOnly && lexeme.RequireBlock && ((ComplexLexeme)lexeme).Block == null) { error = new CompileError(CompileErrorType.LexemeWithoutRequiredBlock, lexeme.Tokens?[0]); } } }
public Function(NmProgram program, string name, FunctionModifier modifier, Type returnType, int scope, List <FunctionParameter> parameters = null, BlockLexeme rawLexeme = null) { Program = program; Name = name; Modifier = modifier; ReturnType = returnType; Parameters = parameters ?? new List <FunctionParameter>(); RawLexeme = rawLexeme; Scope = scope; IsVariadic = false; OriginalName = name; }
private void ResolveLocals(BlockLexeme parent, out CompileError error, ref int index) { error = null; if (parent == null) { return; } foreach (var lexeme in parent.ChildLexemes) { if (lexeme.Type == LexemeType.Var) { var varLexeme = (VarLexeme)lexeme; if (!IdentifierFormat.Match(varLexeme.VarName.StringValue)) { error = new CompileError(CompileErrorType.WrongIdentifierFormat, varLexeme.VarName); return; } var varWithSameName = LocalVariables.Find(p => p.Name == varLexeme.VarName.StringValue); if (varWithSameName != null) { if (HasInStack(parent, varWithSameName.Scope)) { error = new CompileError(CompileErrorType.VariableRedeclaration, varLexeme.VarName); return; } } if (Program.ProgramGlobals.Find(p => p.Name == varLexeme.VarName.StringValue) != null) { error = new CompileError(CompileErrorType.VariableRedeclaration, varLexeme.VarName); return; } Type t; if ((error = Type.GetType(Program, varLexeme.TypeTokens, out t)) != null) { return; } LocalVariables.Add(new Variable(t, varLexeme.VarName.StringValue, parent.Scope, varLexeme.VarName, index++, VariableType.Variable)); varLexeme.Index = index - 1; } if (lexeme.RequireBlock) { ResolveLocals(((ComplexLexeme)lexeme).Block, out error, ref index); if (error != null) { return; } } if (lexeme.Type == LexemeType.Block) { ResolveLocals((BlockLexeme)lexeme, out error, ref index); if (error != null) { return; } } } }
private static void ResolveLexemeTypes(BlockLexeme root, out CompileError error, bool prototypesOnly) { error = null; for (var i = 0; i < root.ChildLexemes.Count; i++) { var lexeme = root.ChildLexemes[i]; if (lexeme.Type == LexemeType.Block) { ResolveLexemeTypes((BlockLexeme)lexeme, out error, prototypesOnly); if (error != null) { return; } } else if (lexeme.Type == LexemeType.Unknown) { LexemeInfo matchedLexeme = LexemePatternToken.GetMatchedLexeme(lexeme.Tokens); if (matchedLexeme != null) { try { root.ChildLexemes[i] = matchedLexeme.CreateLexeme(lexeme.Tokens, prototypesOnly); //if (root.ChildLexemes.Last().Type == LexemeType.Var) //((VarLexeme) root.ChildLexemes.Last()).Index = i; if (!prototypesOnly) { if (root.ChildLexemes[i].Type == LexemeType.Else) { if (i == 0 || (root.ChildLexemes[i - 1].Type != LexemeType.If) && (root.ChildLexemes[i - 1].Type == LexemeType.Block && root.ChildLexemes[i - 2].Type != LexemeType.If)) { error = new CompileError(CompileErrorType.ElseWithoutCondition, lexeme.Tokens[0]); return; } if (root.ChildLexemes[i - 1].Type == LexemeType.If) { (root.ChildLexemes[i - 1] as IfLexeme).ElseLexeme = (ElseLexeme)root.ChildLexemes[i]; } else { (root.ChildLexemes[i - 2] as IfLexeme).ElseLexeme = (ElseLexeme)root.ChildLexemes[i]; } } } } catch (CompileException e) { error = e.ToError(); return; } catch (Exception e) { if (e.InnerException?.GetType() == typeof(CompileException)) { error = ((CompileException)e.InnerException).ToError(); } else { throw e; } return; } } else { error = new CompileError(CompileErrorType.UnknownLexeme, lexeme?.Tokens[0]); return; } } } }