/// <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 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 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 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>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 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 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 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>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 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 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>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>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. } } }
/// <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. } } }
/// <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(); }
//--------------------------------------