private void DequeueIdentifierUsage(Node parent, string error) { Token token = Dequeue(); if (token?.Type == NodeType.Identifier) { Identifier identifier; SymbolLookup lookup = symbolTable.Get(token.Value); if (lookup == null) { identifier = new Identifier(token.Value, Peek() == "." ? IdentifierKind.Class : IdentifierKind.Subroutine, false); } else { identifier = new Identifier(lookup.Name, lookup.Kind, false, lookup.Number); identifier.ClassType = lookup.ClassType; } parent.AddChild(identifier); if (Peek() == "[") { DequeueSymbol(parent, "["); parent.AddChild(ParseExpression()); DequeueSymbol(parent, "]"); } } else { string suffix = token == null ? ", reached end of file instead" : $", got {token} instead"; throw new ApplicationException(error + suffix); } }
public SymbolLookup Add(string name, IdentifierKind kind, string classType) { SymbolLookup symbol = null; if (IsFieldOrStatic(kind)) { int number = classSymbols.Count(s => s.Kind == kind); symbol = new SymbolLookup { Name = name, Kind = kind, Number = number, ClassType = classType }; classSymbols.Add(symbol); } if (IsArgumentOrVar(kind)) { int number = subroutineSymbols.Count(s => s.Kind == kind); if (isMethod && kind == IdentifierKind.Argument) { number++; } symbol = new SymbolLookup { Name = name, Kind = kind, Number = number, ClassType = classType }; subroutineSymbols.Add(symbol); } return(symbol); }
private void DequeueIdentifierDeclaration(Node parent, IdentifierKind kind, string classType, string error) { Token token = Dequeue(); if (token?.Type == NodeType.Identifier) { Identifier identifier; if (SymbolTable.IsClassOrSubroutine(kind)) { identifier = new Identifier(token.Value, kind, true); } else { SymbolLookup symbolLookup = symbolTable.Add(token.Value, kind, classType); if (symbolLookup != null) { identifier = new Identifier(symbolLookup.Name, symbolLookup.Kind, true, symbolLookup.Number); } else { identifier = new Identifier(token.Value, IdentifierKind.Subroutine, true); } } identifier.ClassType = classType; parent.AddChild(identifier); if (Peek() == "[") { DequeueSymbol(parent, "["); parent.AddChild(ParseExpression()); DequeueSymbol(parent, "]"); } } else { string suffix = token == null ? ", reached end of file instead" : $", got {token} instead"; throw new ApplicationException(error + suffix); } }
public SymbolLookup Get(string name) { SymbolLookup subroutineSymbol = subroutineSymbols.SingleOrDefault(s => s.Name == name); return(subroutineSymbol ?? classSymbols.SingleOrDefault(s => s.Name == name)); }