/// <summary>Creates a new string fragment by reading it from the given lexer.</summary> /// <param name="sr">The lexer to read it from.</param> public StringFragment(CodeLexer sr){ sr.Literal=true; // Read off the quote: char Quote=sr.Read(); char Char=sr.Read(); bool Delimited=false; while( Delimited || Char!=Quote && Char!=StringReader.NULL){ if(Char=='\\'&&!Delimited){ Delimited=true; }else{ Delimited=false; Value+=Char; } Char=sr.Read(); } sr.Literal=false; // Read off any junk after the quote: while(sr.ReadJunk()){ sr.DidReadJunk=true; } if(Char==StringReader.NULL){ Error("Unterminated string found."); } }
/// <summary>Creates a new type fragment by reading it from the given lexer.</summary> /// <param name="sr">The lexer to read it from.</param> /// <param name="hasColon">True if a colon (:) should be read from the lexer.</param> public TypeFragment(CodeLexer sr,bool hasColon){ HasColon=hasColon; if(HasColon){ // Read off the colon: sr.Read(); } // Read until some other block can take over: while(true){ char peek=sr.Peek(); if(peek=='<'){ List<TypeFragment> generics=new List<TypeFragment>(); while(true){ // Read off the < or the comma: sr.Read(); generics.Add(new TypeFragment(sr,false)); if(sr.Peek()=='>'){ sr.Read(); GenericSet=generics.ToArray(); break; } } if(sr.Peek()=='['){ SetArray(sr); } break; }else if(peek=='['){ SetArray(sr); break; }else if(peek==','||peek==';'||peek==StringReader.NULL||BracketFragment.AnyBracket(peek)||Operator.IsOperator(peek)){ // Pass control back to the operation: break; } Value+=char.ToLower(sr.Read()); } }
/// <summary>Creates and reads a new if(){} fragment. Note that the else section is not read.</summary> /// <param name="sr">The lexer to read the if condition and its true bracket block from.</param> public IfFragment(CodeLexer sr){ ApplyElseTo=this; Condition=new BracketFragment(sr); IfTrue=new BracketFragment(sr); // Add them as children such that code tree iterators can visit them: AddChild(Condition); AddChild(IfTrue); }
/// <summary>Creates and reads a new for/while loop fragment.</summary> /// <param name="sr">The lexer to read the loop content from.</param> /// <param name="name">This class represents while too. This is the name of the loop; either 'for' or 'while'.</param> public ForFragment(CodeLexer sr,string name){ Value=name; Parameters=new BracketFragment(sr); Body=new BracketFragment(sr); // Add them as children such that code tree iterators can visit them: AddChild(Parameters); AddChild(Body); }
public override AddResult AddTo(CodeFragment to,CodeLexer sr){ if(to.LastChild==null){ Error("A property (."+Value+") was found in an unexpected place."); } // Replace the last child with *THIS*: of=to.LastChild; of.Remove(); to.AddChild(this); return AddResult.Ok; }
/// <summary>Creates a new operator by reading one from given the lexer.</summary> /// <param name="sr">The lexer to read the operator from.</param> public OperatorFragment(CodeLexer sr){ char operatorChar=sr.Read(); // First check if this character plus the next one makes a valid operator (e.g. +=): char peek=sr.Peek(); if(peek!=StringReader.NULL&&Set(""+operatorChar+peek)){ // Yes it does - Make it official by reading it off: sr.Read(); // We called set in the if so don't do it again: return; } Set(""+operatorChar); }
public override AddResult AddTo(CodeFragment to,CodeLexer sr){ if(MethodName.GetType()==typeof(VariableFragment)){ VariableFragment vfrag=(VariableFragment)MethodName; if(vfrag.Value=="new"){ CodeFragment p=to.LastChild; if(p==null||p.GetType()!=typeof(VariableFragment)||((VariableFragment)p).Value!="function"){ // Constructor call. vfrag.Remove(); return new ConstructorFragment(vfrag.GivenType,Brackets).AddTo(to,sr); } } } return base.AddTo(to,sr); }
/// <summary>Creates a new operator by reading one from given the lexer.</summary> /// <param name="sr">The lexer to read the operator from.</param> public OperatorFragment(CodeLexer sr) { char operatorChar = sr.Read(); // First check if this character plus the next one makes a valid operator (e.g. +=): char peek = sr.Peek(); if (peek != StringReader.NULL && Set("" + operatorChar + peek)) { // Yes it does - Make it official by reading it off: sr.Read(); // We called set in the if so don't do it again: return; } Set("" + operatorChar); }
/// <summary>Creates a new BracketFragment.</summary> /// <param name="sr">The lexer to read the bracket content from.</param> /// <param name="readBracket">True if the brackets should be read off (i.e. the first thing done is read a single character). False otherwise.</param> public BracketFragment(CodeLexer sr,bool readBracket){ if(readBracket){ int type=IsBracket(sr.Read()); if(type==-1){ // Seek back just one - we want to re-read the thing we just tested for bracketness: sr.Position--; // No bracket; their implicit - read single operation: AddChild(new OperationFragment(sr,this)); // And stop there: return; }else{ // Grab the brackets: Bracket=Brackets[type]; CloseBracket=EndBrackets[type]; } } char peek=sr.Peek(); bool bracket=(IsEndBracket(peek)!=-1); while(peek!=StringReader.NULL && !bracket){ // Add the operation: AddChild(new OperationFragment(sr,this)); // What's next? peek=sr.Peek(); // Is it a bracket? bracket=(IsEndBracket(peek)!=-1); } if(bracket){ // Read the last bracket off: sr.Read(); } }
/// <summary>Creates a new type fragment by reading it from the given lexer.</summary> /// <param name="sr">The lexer to read it from.</param> /// <param name="hasColon">True if a colon (:) should be read from the lexer.</param> public TypeFragment(CodeLexer sr, bool hasColon) { HasColon = hasColon; if (HasColon) { // Read off the colon: sr.Read(); } // Read until some other block can take over: while (true) { char peek = sr.Peek(); if (peek == '<') { List <TypeFragment> generics = new List <TypeFragment>(); while (true) { // Read off the < or the comma: sr.Read(); generics.Add(new TypeFragment(sr, false)); if (sr.Peek() == '>') { sr.Read(); GenericSet = generics.ToArray(); break; } } if (sr.Peek() == '[') { SetArray(sr); } break; } else if (peek == '[') { SetArray(sr); break; } else if (peek == ',' || peek == ';' || peek == StringReader.NULL || BracketFragment.AnyBracket(peek) || Operator.IsOperator(peek)) { // Pass control back to the operation: break; } Value += char.ToLower(sr.Read()); } }
/// <summary>Reads array indices (array[,,,] = 3 dimensions) from the given lexer and sets the dimensions from the number of them.</summary> /// <param name="sr">The lexer to read the indices from.</param> private void SetArray(CodeLexer sr) { IsArray = true; // Read off the [ : sr.Read(); while (sr.Peek() != ']') { Dimensions++; char C = sr.Read(); if (C != ',') { Error("Bad array type (" + ToString() + "). myArray:String[]=new String[](40); or myArray:String[]=new String[]{\"V1\",\"V2\"}; is the correct syntax."); } } // read off the ] : sr.Read(); }
/// <summary>Creates a new BracketFragment.</summary> /// <param name="sr">The lexer to read the bracket content from.</param> /// <param name="readBracket">True if the brackets should be read off (i.e. the first thing done is read a single character). False otherwise.</param> public BracketFragment(CodeLexer sr, bool readBracket) { if (readBracket) { int type = IsBracket(sr.Read()); if (type == -1) { // Seek back just one - we want to re-read the thing we just tested for bracketness: sr.Position--; // No bracket; their implicit - read single operation: AddChild(new OperationFragment(sr, this)); // And stop there: return; } else { // Grab the brackets: Bracket = Brackets[type]; CloseBracket = EndBrackets[type]; } } char peek = sr.Peek(); bool bracket = (IsEndBracket(peek) != -1); while (peek != StringReader.NULL && !bracket) { // Add the operation: AddChild(new OperationFragment(sr, this)); // What's next? peek = sr.Peek(); // Is it a bracket? bracket = (IsEndBracket(peek) != -1); } if (bracket) { // Read the last bracket off: sr.Read(); } }
/// <summary>Creates a property fragment by reading it from the given lexer.</summary> /// <param name="sr">The lexer to read the fragment from.</param> public PropertyFragment(CodeLexer sr){ // Skip the dot: sr.Read(); // Read a 'variable': Value+=char.ToLower(sr.Read()); while(true){ char peek=sr.Peek(); if(peek==';'||peek==','||peek=='.'||peek==StringReader.NULL||BracketFragment.AnyBracket(peek)){ // Pass control back to the operation: break; } Handler handle=Handlers.Find(peek); if(handle!=Handler.Stop&&handle!=Handler.Variable&&handle!=Handler.Number&&handle!=Handler.Property){ break; } Value+=char.ToLower(sr.Read()); } }
public override AddResult AddTo(CodeFragment to, CodeLexer sr) { if (MethodName.GetType() == typeof(VariableFragment)) { VariableFragment vfrag = (VariableFragment)MethodName; if (vfrag.Value == "new") { CodeFragment p = to.LastChild; if (p == null || p.GetType() != typeof(VariableFragment) || ((VariableFragment)p).Value != "function") { // Constructor call. vfrag.Remove(); return(new ConstructorFragment(vfrag.GivenType, Brackets).AddTo(to, sr)); } } } return(base.AddTo(to, sr)); }
/// <summary>Reads a code fragment from the code using a known handler.</summary> /// <param name="handle">The handler to use.</param> /// <param name="sr">The raw code stream</param> /// <returns>A new code fragment, or null if told to stop with Handler.Stop.</returns> public static CodeFragment Handle(Handler handle,CodeLexer sr){ if(handle==Handler.Brackets){ return new BracketFragment(sr); }else if(handle==Handler.String){ return new StringFragment(sr); }else if(handle==Handler.Type){ return new TypeFragment(sr); }else if(handle==Handler.Operator){ return new OperatorFragment(sr); }else if(handle==Handler.Number){ return new NumberFragment(sr); }else if(handle==Handler.Variable){ return new VariableFragment(sr); }else if(handle==Handler.Property){ return new PropertyFragment(sr); }else{ return null; } }
/// <summary>Creates a property fragment by reading it from the given lexer.</summary> /// <param name="sr">The lexer to read the fragment from.</param> public PropertyFragment(CodeLexer sr) { // Skip the dot: sr.Read(); // Read a 'variable': Value += char.ToLower(sr.Read()); while (true) { char peek = sr.Peek(); if (peek == ';' || peek == ',' || peek == '.' || peek == StringReader.NULL || BracketFragment.AnyBracket(peek)) { // Pass control back to the operation: break; } Handler handle = Handlers.Find(peek); if (handle != Handler.Stop && handle != Handler.Variable && handle != Handler.Number && handle != Handler.Property) { break; } Value += char.ToLower(sr.Read()); } }
/// <summary>Creates a new variable fragment by reading it from the given lexer.</summary> /// <param name="sr">The lexer to read the variable from.</param> public VariableFragment(CodeLexer sr){ Value+=char.ToLower(sr.Read()); // Read until some other block can take over: while(true){ char peek=sr.Peek(); if(peek==';'||peek==','||peek==StringReader.NULL||BracketFragment.AnyBracket(peek)){ // Pass control back to the operation: break; } if(sr.PeekJunk()){ // Is Value anything special? if(Value=="var"){ break; }else if(Value=="private"){ break; }else if(Value=="function"){ break; }else if(Value=="class"){ break; }else if(Value=="new"){ GivenType=new TypeFragment(sr,false); break; }else if(IsKeyword()){ break; } } Handler handle=Handlers.Find(peek); if(handle!=Handler.Stop&&handle!=Handler.Variable&&handle!=Handler.Number){ break; } Value+=char.ToLower(sr.Read()); } }
/// <summary>Reads a new number fragment from the given lexer.</summary> /// <param name="sr">The lexer to read the number from.</param> public NumberFragment(CodeLexer sr){ int index=IsOfType(Number,sr.Peek()); while(index!=-1){ Value+=sr.Read(); if(index==0){ // Got a dot in it - must be a float. Float=true; } char peek=sr.Peek(); if(peek=='f'){ Float=true; sr.Read(); return; }else if(peek=='H'&&sr.Peek(1)=='z'){ Float=true; sr.Read(); sr.Read(); return; }else{ index=IsOfType(Number,peek); } } }
/// <summary>Creates a new string fragment by reading it from the given lexer.</summary> /// <param name="sr">The lexer to read it from.</param> public StringFragment(CodeLexer sr) { sr.Literal = true; // Read off the quote: char Quote = sr.Read(); char Char = sr.Read(); bool Delimited = false; while (Delimited || Char != Quote && Char != StringReader.NULL) { if (Char == '\\' && !Delimited) { Delimited = true; } else { Delimited = false; Value += Char; } Char = sr.Read(); } sr.Literal = false; // Read off any junk after the quote: while (sr.ReadJunk()) { sr.DidReadJunk = true; } if (Char == StringReader.NULL) { Error("Unterminated string found."); } }
/// <summary>Reads array indices (array[,,,] = 3 dimensions) from the given lexer and sets the dimensions from the number of them.</summary> /// <param name="sr">The lexer to read the indices from.</param> private void SetArray(CodeLexer sr){ IsArray=true; // Read off the [ : sr.Read(); while(sr.Peek()!=']'){ Dimensions++; char C=sr.Read(); if(C!=','){ Error("Bad array type ("+ToString()+"). myArray:String[]=new String[](40); or myArray:String[]=new String[]{\"V1\",\"V2\"}; is the correct syntax."); } } // read off the ] : sr.Read(); }
public override AddResult AddTo(CodeFragment to,CodeLexer sr){ if(Bracket=='['){ if(to.LastChild==null){ Error("Unexpected indexing. must be something[index]."); }else{ CodeFragment var=to.LastChild; var.Remove(); return new IndexFragment(this,var).AddTo(to,sr); } }else if(Bracket=='{'&&to.LastChild!=null){ // new TYPE[]{default,default..}; if(to.LastChild.GetType()==typeof(VariableFragment)&&((VariableFragment)(to.LastChild)).Value=="new"){ VariableFragment var=(VariableFragment)(to.LastChild); if(var.GivenType==null){ Error("new must always be followed by a type name."); }else if(!var.GivenType.IsArray){ Error("new Type{} only works when Type is an array and curley brackets define it's default values e.g. new int[]{1,2}"); }else{ var.Remove(); return new ArrayFragment(var.GivenType,this).AddTo(to,sr); } } }else if(Bracket=='('&&to.LastChild!=null){ Type type=to.LastChild.GetType(); if(type==typeof(IndexFragment)||type==typeof(PropertyFragment)||(type==typeof(VariableFragment)&&!((VariableFragment)(to.LastChild)).IsKeyword())){ // Method call! CodeFragment meth=to.LastChild; meth.Remove(); return new MethodFragment(this,meth).AddTo(to,sr); } } return base.AddTo(to,sr); }
/// <summary>Creates a new BracketFragment.</summary> /// <param name="sr">The lexer to read the bracket content from.</param> public BracketFragment(CodeLexer sr):this(sr,true){}
/// <summary>Compiles the given code now deriving from the given object.</summary> /// <param name="code">The code to compile</param> /// <param name="baseType">The type to inherit from. If null, the code will inherit from the default Script type.</param> /// <param name="aotFile">A DLL path to write the compiled code to (For e.g. AOT compilation).</param> public void Compile(string code, Type baseType, string aotFile, string aotAssemblyName) { Code = code; if (baseType == null) { baseType = typeof(Script); } // Are we compiling to a file? string aotFilename = ""; string assemblyPath = null; bool aot = !string.IsNullOrEmpty(aotFile); // The assembly name: AssemblyName assemblyName = null; if (aot) { // Grab the file name (used below too): aotFilename = System.IO.Path.GetFileName(aotFile); // Setup the assembly name: assemblyName = new AssemblyName(aotAssemblyName); } else { assemblyName = new AssemblyName("$SS_" + ModuleCounter); } // Assembly access: AssemblyBuilderAccess access = AssemblyBuilderAccess.Run; if (aot) { // We're ahead-of-time compiling this to a file. // Grab the directory the file must go in: assemblyPath = System.IO.Path.GetDirectoryName(aotFile); if (assemblyPath != null) { if (!Directory.Exists(assemblyPath)) { Directory.CreateDirectory(assemblyPath); } } access = AssemblyBuilderAccess.Save; } // Create the assembly builder. If we're AOT compiling, it's saveable. AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, access, assemblyPath); if (aot) { // Create the module: Builder = assemblyBuilder.DefineDynamicModule("SS-DMOD", aotFilename); } else { Builder = assemblyBuilder.DefineDynamicModule("SS-DMOD"); } ModuleCounter++; // Ok - let's start compiling. Define a base class that all code goes into: BaseClass = new CompiledClass(); // That class will be known as.. BaseClass.StartType("NitroScriptCode", this, baseType); // Start parsing the code into a tree of fragments: CodeLexer sr = new CodeLexer(Code); BaseClass.ClassFragment = new BaseFragment(sr); // Search the fragments for any classes: FindClasses(BaseClass.ClassFragment); // Compile the classes we found: foreach (KeyValuePair <string, CompiledClass> kvp in Types) { kvp.Value.Compile(); } // Compile the base class: BaseClass.Compile(); CompiledType = BaseClass.compiledType; Types = null; BaseClass = null; #if !UNITY_WEBPLAYER if (aot) { // Great - overwrite it. if (File.Exists(aotFile)) { if (OnAotFileExists == null) { File.Delete(aotFile); } else { OnAotFileExists(aotFile); } } assemblyBuilder.Save(aotFilename); } #endif }
public override AddResult AddTo(CodeFragment to, CodeLexer sr) { base.AddTo(to, sr); return(AddResult.Stop); }
/// <summary>Creates a new type fragment by reading it and a preceeding colon from the given lexer.</summary> /// <param name="sr">The lexer to read from.</param> public TypeFragment(CodeLexer sr):this(sr,true){}
public override AddResult AddTo(CodeFragment to,CodeLexer sr){ if(Value==""){ return AddResult.Ok; }else if(Value=="var"){ // We're reading a local: return AddResult.Local; }else if(Value=="for" || Value=="while"){ return new ForFragment(sr,Value).AddTo(to,sr); }else if(Value=="switch"){ return new SwitchFragment(sr).AddTo(to,sr); }else if(Value=="if"){ return new IfFragment(sr).AddTo(to,sr); }else if(Value=="else"){ CodeFragment previous=to.ParentFragment; // Parent->prev operation->last object. Should be an IF. if(previous==null||((previous=previous.LastChild)==null)||((previous=previous.LastChild)==null)||previous.GetType()!=typeof(IfFragment)){ Error("Else can only be applied to an if. E.g. if(){}else{}."); } IfFragment ifFrag=(IfFragment)previous; ifFrag.ApplyElseTo.SetIfFalse(new BracketFragment(sr)); return AddResult.Stop; }else if(Value=="elseif"){ CodeFragment previous=to.ParentFragment; // Parent->prev operation->last object. Should be an IF. if(previous==null||((previous=previous.LastChild)==null)||((previous=previous.LastChild)==null)||previous.GetType()!=typeof(IfFragment)){ Error("Else if can only be applied to an if. E.g. if(){}else if{}.."); } IfFragment ifFrag=(IfFragment)previous; IfFragment newfrag=new IfFragment(sr); BracketFragment bf=new BracketFragment(); OperationFragment op=new OperationFragment(); op.AddChild(newfrag); bf.AddChild(op); ifFrag.ApplyElseTo.SetIfFalse(bf); ifFrag.ApplyElseTo=newfrag; return AddResult.Stop; }else{ return base.AddTo(to,sr); } }
/// <summary>Reads a new operation from the given lexer.</summary> /// <param name="sr">The lexer to read the operation from.</param> /// <param name="parent">The fragment to parent the operation to.</param> public OperationFragment(CodeLexer sr,CodeFragment parent){ ParentFragment=parent; LineNumber=sr.LineNumber; bool localMode=false; while(true){ char peek=sr.Peek(); if(peek==StringReader.NULL){ return; } if(peek==';'||peek==','){ // Read it off: sr.Read(); return; } Handler handler=Handlers.Find(peek); if(handler==Handler.Stop){ return; } // Handle the fragment: CodeFragment fragment; try{ // Try to get the code fragment: fragment=Handlers.Handle(handler,sr); }catch(CompilationException e){ if(e.LineNumber==-1){ // Setup line number: e.LineNumber=LineNumber; } // Rethrow: throw e; } if(localMode){ // Should always be a VariableFragment: if(fragment.GetType()==typeof(VariableFragment)){ VariableFragment local=(VariableFragment)fragment; local.AfterVar=true; } localMode=false; } // Try adding the fragment to the operation: AddResult status=fragment.AddTo(this,sr); // What was the outcome? switch(status){ case AddResult.Stop: // Halt. return; case AddResult.Local: // Local next: localMode=true; break; // Ok otherwise. } } }
public BaseFragment(CodeLexer sr) : base(sr, false) { }
/// <summary>Creates and reads a new switch fragment.</summary> /// <param name="sr">The lexer to read the switch content from.</param> public SwitchFragment(CodeLexer sr){ Parameters=new BracketFragment(sr); Body=new BracketFragment(sr); }
/// <summary>Adds this fragment as a child to the given fragment. /// It may be overriden by some types of fragment as they may wish to handle it differently.</summary> /// <param name="to">The parent to add this fragment to.</param> /// <param name="sr">The lexer containing the original text code.</param> public virtual AddResult AddTo(CodeFragment to,CodeLexer sr){ to.AddChild(this); return AddResult.Ok; }
/// <summary>Creates and reads a new switch fragment.</summary> /// <param name="sr">The lexer to read the switch content from.</param> public SwitchFragment(CodeLexer sr) { Parameters = new BracketFragment(sr); Body = new BracketFragment(sr); }
//--------------------------------------
/// <summary>Creates a new BracketFragment.</summary> /// <param name="sr">The lexer to read the bracket content from.</param> public BracketFragment(CodeLexer sr) : this(sr, true) { }
/// <summary>Adds this fragment as a child to the given fragment. /// It may be overriden by some types of fragment as they may wish to handle it differently.</summary> /// <param name="to">The parent to add this fragment to.</param> /// <param name="sr">The lexer containing the original text code.</param> public virtual AddResult AddTo(CodeFragment to, CodeLexer sr) { to.AddChild(this); return(AddResult.Ok); }
/// <summary>Compiles the given code now deriving from the given object.</summary> /// <param name="code">The code to compile</param> /// <param name="baseType">The type to inherit from. If null, the code will inherit from the default Script type.</param> /// <param name="aotFile">A DLL path to write the compiled code to (For e.g. AOT compilation).</param> public void Compile(string code,Type baseType,string aotFile,string aotAssemblyName){ Code=code; if(baseType==null){ baseType=typeof(Script); } // Are we compiling to a file? string aotFilename=""; string assemblyPath=null; bool aot=!string.IsNullOrEmpty(aotFile); // The assembly name: AssemblyName assemblyName=null; if(aot){ // Grab the file name (used below too): aotFilename=System.IO.Path.GetFileName(aotFile); // Setup the assembly name: assemblyName=new AssemblyName(aotAssemblyName); }else{ assemblyName=new AssemblyName("$SS_"+ModuleCounter); } // Assembly access: AssemblyBuilderAccess access=AssemblyBuilderAccess.Run; if(aot){ // We're ahead-of-time compiling this to a file. // Grab the directory the file must go in: assemblyPath=System.IO.Path.GetDirectoryName(aotFile); if(assemblyPath!=null){ if(!Directory.Exists(assemblyPath)){ Directory.CreateDirectory(assemblyPath); } } access=AssemblyBuilderAccess.Save; } // Create the assembly builder. If we're AOT compiling, it's saveable. AssemblyBuilder assemblyBuilder=AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,access,assemblyPath); if(aot){ // Create the module: Builder=assemblyBuilder.DefineDynamicModule("SS-DMOD",aotFilename); }else{ Builder=assemblyBuilder.DefineDynamicModule("SS-DMOD"); } ModuleCounter++; // Ok - let's start compiling. Define a base class that all code goes into: BaseClass=new CompiledClass(); // That class will be known as.. BaseClass.StartType("NitroScriptCode",this,baseType); // Start parsing the code into a tree of fragments: CodeLexer sr=new CodeLexer(Code); BaseClass.ClassFragment=new BaseFragment(sr); // Search the fragments for any classes: FindClasses(BaseClass.ClassFragment); // Compile the classes we found: foreach(KeyValuePair<string,CompiledClass>kvp in Types){ kvp.Value.Compile(); } // Compile the base class: BaseClass.Compile(); CompiledType=BaseClass.compiledType; Types=null; BaseClass=null; if(aot){ // Great - overwrite it. if(File.Exists(aotFile)){ if(OnAotFileExists==null){ File.Delete(aotFile); }else{ OnAotFileExists(aotFile); } } assemblyBuilder.Save(aotFilename); } }
public override AddResult AddTo(CodeFragment to, CodeLexer sr) { if (Value == "") { return(AddResult.Ok); } else if (Value == "var") { // We're reading a local: return(AddResult.Local); } else if (Value == "for" || Value == "while") { return(new ForFragment(sr, Value).AddTo(to, sr)); } else if (Value == "switch") { return(new SwitchFragment(sr).AddTo(to, sr)); } else if (Value == "if") { return(new IfFragment(sr).AddTo(to, sr)); } else if (Value == "else") { CodeFragment previous = to.ParentFragment; // Parent->prev operation->last object. Should be an IF. if (previous == null || ((previous = previous.LastChild) == null) || ((previous = previous.LastChild) == null) || previous.GetType() != typeof(IfFragment)) { Error("Else can only be applied to an if. E.g. if(){}else{}."); } IfFragment ifFrag = (IfFragment)previous; ifFrag.ApplyElseTo.SetIfFalse(new BracketFragment(sr)); return(AddResult.Stop); } else if (Value == "elseif") { CodeFragment previous = to.ParentFragment; // Parent->prev operation->last object. Should be an IF. if (previous == null || ((previous = previous.LastChild) == null) || ((previous = previous.LastChild) == null) || previous.GetType() != typeof(IfFragment)) { Error("Else if can only be applied to an if. E.g. if(){}else if{}.."); } IfFragment ifFrag = (IfFragment)previous; IfFragment newfrag = new IfFragment(sr); BracketFragment bf = new BracketFragment(); OperationFragment op = new OperationFragment(); op.AddChild(newfrag); bf.AddChild(op); ifFrag.ApplyElseTo.SetIfFalse(bf); ifFrag.ApplyElseTo = newfrag; return(AddResult.Stop); } else { return(base.AddTo(to, sr)); } }
/// <summary>Creates a new type fragment by reading it and a preceeding colon from the given lexer.</summary> /// <param name="sr">The lexer to read from.</param> public TypeFragment(CodeLexer sr) : this(sr, true) { }
public BaseFragment(CodeLexer sr):base(sr,false){}
/// <summary>Reads a new operation from the given lexer.</summary> /// <param name="sr">The lexer to read the operation from.</param> /// <param name="parent">The fragment to parent the operation to.</param> public OperationFragment(CodeLexer sr, CodeFragment parent) { ParentFragment = parent; LineNumber = sr.LineNumber; bool localMode = false; while (true) { char peek = sr.Peek(); if (peek == StringReader.NULL) { return; } if (peek == ';' || peek == ',') { // Read it off: sr.Read(); return; } Handler handler = Handlers.Find(peek); if (handler == Handler.Stop) { return; } // Handle the fragment: CodeFragment fragment; try{ // Try to get the code fragment: fragment = Handlers.Handle(handler, sr); }catch (CompilationException e) { if (e.LineNumber == -1) { // Setup line number: e.LineNumber = LineNumber; } // Rethrow: throw e; } if (localMode) { // Should always be a VariableFragment: if (fragment.GetType() == typeof(VariableFragment)) { VariableFragment local = (VariableFragment)fragment; local.AfterVar = true; } localMode = false; } // Try adding the fragment to the operation: AddResult status = fragment.AddTo(this, sr); // What was the outcome? switch (status) { case AddResult.Stop: // Halt. return; case AddResult.Local: // Local next: localMode = true; break; // Ok otherwise. } } }
public override AddResult AddTo(CodeFragment to,CodeLexer sr){ base.AddTo(to,sr); return AddResult.Stop; }
public override AddResult AddTo(CodeFragment to,CodeLexer sr){ if(to.LastChild==null||!to.LastChild.Typeable()){ Error("A type ("+ToString()+") was found in an unexpected place."); } to.LastChild.GivenType=this; return AddResult.Ok; }