public void Add(Token token, OpCode op, string stringValue, params int[] args) { List<int> nums = new List<int>(args); nums.Insert(0, (int)op); this.byteCode.Add(nums.ToArray()); this.tokens.Add(token); this.stringArgs.Add(stringValue); }
public int GetVarId(Token variableToken, bool isRead) { int id; if (this.idsByVar.TryGetValue(variableToken.Value, out id)) { return id; } if (isRead) { throw new ParserException(variableToken, "'" + variableToken.Value + "' is not defined anywhere."); } throw new ParserException(variableToken, "BAD STATE - CRAYON BUG!!!! A variable assignment was not registered by the parse tree traversal."); }
private void Initialize(Token annotationToken, TokenStream proxyTokenStream) { this.Token = annotationToken; Token token = proxyTokenStream.Pop(); if (!Parser.IsValidIdentifier(token.Value)) throw new ParserException(annotationToken, "Invalid type"); this.Name = token.Value; while (proxyTokenStream.PopIfPresent(".")) { this.Name += "."; this.Name += proxyTokenStream.PopValue(); } List<AnnotatedType> generics = new List<AnnotatedType>(); if (proxyTokenStream.PopIfPresent("<")) { while (proxyTokenStream.HasMore && !proxyTokenStream.IsNext(">")) { if (generics.Count > 0 && !proxyTokenStream.PopIfPresent(",")) { throw new ParserException(annotationToken, "Expected comma in generic list"); } AnnotatedType genericItem = new AnnotatedType(annotationToken, proxyTokenStream); generics.Add(genericItem); } if (!proxyTokenStream.PopIfPresent(">")) { throw new ParserException(annotationToken, "Unclosed generic bracket."); } } this.Generics = generics.ToArray(); }
internal static void VerifyIdentifier(Token token) { if (!IsValidIdentifier(token.Value)) { throw new ParserException(token, "Identifier expected."); } }
public void RegisterConst(Token nameToken, Expression value) { this.VerifyNameFree(nameToken); this.things.Add(nameToken.Value); this.constLookup[nameToken.Value] = value; }
private void VerifyNameFree(Token nameToken) { if (things.Contains(nameToken.Value)) { throw new ParserException(nameToken, "This name has already been used."); } }
public int RegisterByteCodeSwitch(Token switchToken, Dictionary<int, int> chunkIdsToOffsets, Dictionary<int, int> integersToChunkIds, Dictionary<string, int> stringsToChunkIds, bool isIntegerSwitch) { int switchId; if (isIntegerSwitch) { switchId = byteCodeSwitchIntegerToOffsets.Count; Dictionary<int, int> integersToOffsets = new Dictionary<int, int>(); foreach (int key in integersToChunkIds.Keys) { int chunkId = integersToChunkIds[key]; integersToOffsets[key] = chunkIdsToOffsets[chunkId]; } byteCodeSwitchIntegerToOffsets.Add(integersToOffsets); } else { switchId = byteCodeSwitchStringToOffsets.Count; Dictionary<string, int> stringsToOffsets = new Dictionary<string, int>(); foreach (string key in stringsToChunkIds.Keys) { int chunkId = stringsToChunkIds[key]; stringsToOffsets[key] = chunkIdsToOffsets[chunkId]; } byteCodeSwitchStringToOffsets.Add(stringsToOffsets); } return switchId; }
public ParserException(Token token, string message) : base(InterpretToken(token) + message) { }
private static string InterpretToken(Token token) { if (token == null) return ""; return token.FileName + ", Line: " + (token.Line + 1) + ", Col: " + (token.Col + 1) + ", "; }
public void Add(Token token, OpCode op, params int[] args) { this.Add(token, op, null, args); }
public static Expression ConvertStaticReferenceToExpression(Executable item, Token primaryToken, Executable owner) { if (item is Namespace) return new PartialNamespaceReference(primaryToken, ((Namespace)item).Name, owner); if (item is ClassDefinition) return new ClassReference(primaryToken, (ClassDefinition)item, owner); if (item is EnumDefinition) throw new ParserException(primaryToken, "Cannot create reference to enum. Must complete reference to enum member."); if (item is ConstStatement) { // TODO: do this properly. // Must create a new parse node that contains the value rather than use the one from conststatement, otherwise the tokens will be wrong. // It'd be super useful if there was an IConstant interface for expressions that had a clone method that took in a new token. //return ((ConstStatement)exec).Expression; throw new Exception(); } if (item is FunctionDefinition) return new FunctionReference(primaryToken, (FunctionDefinition)item, owner); throw new System.InvalidOperationException(); // what? }
public AnnotatedType(Token stringToken, TokenStream proxyTokenStream) { this.Initialize(stringToken, proxyTokenStream); }
public Executable[] ImportLibrary(Parser parser, Token throwToken, string name) { name = name.Split('.')[0]; if (alreadyImported.Contains(name)) { return EMPTY_EXECUTABLE; } alreadyImported.Add(name); string dllPath = this.GetSystemLibraryPath(name); if (dllPath == null) { return EMPTY_EXECUTABLE; } System.Reflection.Assembly assembly = null; try { assembly = System.Reflection.Assembly.LoadFrom(dllPath); } catch (Exception) { throw new ParserException(throwToken, "Could not import library: " + name); } ILibraryConfig libraryConfig = assembly.CreateInstance(name + ".LibraryConfig") as ILibraryConfig; if (libraryConfig == null) { throw new ParserException(throwToken, "Error creating LibraryConfig instance in Library '" + name + "'"); } this.importedLibraries[name] = libraryConfig; this.librariesByKey[name.ToLowerInvariant()] = libraryConfig; string oldSystemLibrary = parser.CurrentSystemLibrary; parser.CurrentSystemLibrary = name; string libraryCode = libraryConfig.GetEmbeddedCode(); Executable[] libraryParseTree = parser.ParseInterpretedCode("[" + name + "]", libraryCode, name); parser.CurrentSystemLibrary = oldSystemLibrary; return libraryParseTree; }
private static void EnsureUsed(Token token, bool outputUsed) { if (!outputUsed) { throw new ParserException(token, "Cannot have this expression here. It does nothing. Did you mean to store this output into a variable or return it?"); } }
private BinaryOps ConvertOpString(Token token) { switch (token.Value) { case "++": return BinaryOps.ADDITION; case "+=": return BinaryOps.ADDITION; case "--": return BinaryOps.SUBTRACTION; case "-=": return BinaryOps.SUBTRACTION; case "*=": return BinaryOps.MULTIPLICATION; case "/=": return BinaryOps.DIVISION; case "%=": return BinaryOps.MODULO; case "&=": return BinaryOps.BITWISE_AND; case "|=": return BinaryOps.BITWISE_OR; case "^=": return BinaryOps.BITWISE_XOR; case "<<=": return BinaryOps.BIT_SHIFT_LEFT; case ">>=": return BinaryOps.BIT_SHIFT_RIGHT; default: throw new ParserException(token, "Unrecognized op."); } }