510 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			510 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| 
								 | 
							
								package webidl;
							 | 
						||
| 
								 | 
							
								import webidl.Data;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private enum Token {
							 | 
						||
| 
								 | 
							
									TEof;
							 | 
						||
| 
								 | 
							
									TId( s : String );
							 | 
						||
| 
								 | 
							
									TPOpen;
							 | 
						||
| 
								 | 
							
									TPClose;
							 | 
						||
| 
								 | 
							
									TBrOpen;
							 | 
						||
| 
								 | 
							
									TBrClose;
							 | 
						||
| 
								 | 
							
									TBkOpen;
							 | 
						||
| 
								 | 
							
									TBkClose;
							 | 
						||
| 
								 | 
							
									TSemicolon;
							 | 
						||
| 
								 | 
							
									TComma;
							 | 
						||
| 
								 | 
							
									TOp( op : String );
							 | 
						||
| 
								 | 
							
									TString( str : String );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Parser {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var line : Int;
							 | 
						||
| 
								 | 
							
									var input : haxe.io.Input;
							 | 
						||
| 
								 | 
							
									var char : Int;
							 | 
						||
| 
								 | 
							
									var ops : Array<Bool>;
							 | 
						||
| 
								 | 
							
									var idents : Array<Bool>;
							 | 
						||
| 
								 | 
							
									var tokens : Array<Token>;
							 | 
						||
| 
								 | 
							
									var pos = 0;
							 | 
						||
| 
								 | 
							
									var fileName : String;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function new() {
							 | 
						||
| 
								 | 
							
										var opChars = "+*/-=!><&|^%~";
							 | 
						||
| 
								 | 
							
										var identChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
							 | 
						||
| 
								 | 
							
										idents = new Array();
							 | 
						||
| 
								 | 
							
										ops = new Array();
							 | 
						||
| 
								 | 
							
										for( i in 0...identChars.length )
							 | 
						||
| 
								 | 
							
											idents[identChars.charCodeAt(i)] = true;
							 | 
						||
| 
								 | 
							
										for( i in 0...opChars.length )
							 | 
						||
| 
								 | 
							
											ops[opChars.charCodeAt(i)] = true;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function parseFile( fileName : String, input : haxe.io.Input ) {
							 | 
						||
| 
								 | 
							
										this.fileName = fileName;
							 | 
						||
| 
								 | 
							
										pos = 0;
							 | 
						||
| 
								 | 
							
										line = 1;
							 | 
						||
| 
								 | 
							
										char = -1;
							 | 
						||
| 
								 | 
							
										tokens = [];
							 | 
						||
| 
								 | 
							
										this.input = input;
							 | 
						||
| 
								 | 
							
										var out = [];
							 | 
						||
| 
								 | 
							
										while( true ) {
							 | 
						||
| 
								 | 
							
											var tk = token();
							 | 
						||
| 
								 | 
							
											if( tk == TEof ) break;
							 | 
						||
| 
								 | 
							
											push(tk);
							 | 
						||
| 
								 | 
							
											out.push(parseDecl());
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return out;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function parseDecl() {
							 | 
						||
| 
								 | 
							
										var attr = attributes();
							 | 
						||
| 
								 | 
							
										var pmin = this.pos;
							 | 
						||
| 
								 | 
							
										switch( token() ) {
							 | 
						||
| 
								 | 
							
										case TId("interface"):
							 | 
						||
| 
								 | 
							
											var name = ident();
							 | 
						||
| 
								 | 
							
											ensure(TBrOpen);
							 | 
						||
| 
								 | 
							
											var fields = [];
							 | 
						||
| 
								 | 
							
											while( true ) {
							 | 
						||
| 
								 | 
							
												var tk = token();
							 | 
						||
| 
								 | 
							
												if( tk == TBrClose ) break;
							 | 
						||
| 
								 | 
							
												push(tk);
							 | 
						||
| 
								 | 
							
												fields.push(parseField());
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											ensure(TSemicolon);
							 | 
						||
| 
								 | 
							
											return { pos : makePos(pmin), kind : DInterface(name, attr, fields) };
							 | 
						||
| 
								 | 
							
										case TId("enum"):
							 | 
						||
| 
								 | 
							
											var name = ident();
							 | 
						||
| 
								 | 
							
											ensure(TBrOpen);
							 | 
						||
| 
								 | 
							
											var values = [];
							 | 
						||
| 
								 | 
							
											if( !maybe(TBrClose) )
							 | 
						||
| 
								 | 
							
												while( true ) {
							 | 
						||
| 
								 | 
							
													switch( token() ) {
							 | 
						||
| 
								 | 
							
													case TString(str): values.push(str);
							 | 
						||
| 
								 | 
							
													case var tk: unexpected(tk);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													switch( token() ) {
							 | 
						||
| 
								 | 
							
													case TBrClose: break;
							 | 
						||
| 
								 | 
							
													case TComma: continue;
							 | 
						||
| 
								 | 
							
													case var tk: unexpected(tk);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											ensure(TSemicolon);
							 | 
						||
| 
								 | 
							
											return { pos : makePos(pmin), kind : DEnum(name, values) };
							 | 
						||
| 
								 | 
							
										case TId(name):
							 | 
						||
| 
								 | 
							
											if( attr.length > 0 )
							 | 
						||
| 
								 | 
							
												throw "assert";
							 | 
						||
| 
								 | 
							
											ensure(TId("implements"));
							 | 
						||
| 
								 | 
							
											var intf = ident();
							 | 
						||
| 
								 | 
							
											ensure(TSemicolon);
							 | 
						||
| 
								 | 
							
											return { pos : makePos(pmin), kind : DImplements(name, intf) };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										case var tk:
							 | 
						||
| 
								 | 
							
											return unexpected(tk);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function attributes() {
							 | 
						||
| 
								 | 
							
										if( !maybe(TBkOpen) )
							 | 
						||
| 
								 | 
							
											return [];
							 | 
						||
| 
								 | 
							
										var attrs = [];
							 | 
						||
| 
								 | 
							
										while( true ) {
							 | 
						||
| 
								 | 
							
											var attr = switch( ident() ) {
							 | 
						||
| 
								 | 
							
											case "Value": AValue;
							 | 
						||
| 
								 | 
							
											case "Ref": ARef;
							 | 
						||
| 
								 | 
							
											case "Const": AConst;
							 | 
						||
| 
								 | 
							
											case "NoDelete": ANoDelete;
							 | 
						||
| 
								 | 
							
											case "Prefix":
							 | 
						||
| 
								 | 
							
												ensure(TOp("="));
							 | 
						||
| 
								 | 
							
												APrefix(switch( token() ) { case TString(s): s; case var tk: unexpected(tk); });
							 | 
						||
| 
								 | 
							
											case "JSImplementation":
							 | 
						||
| 
								 | 
							
												ensure(TOp("="));
							 | 
						||
| 
								 | 
							
												AJSImplementation(switch( token() ) { case TString(s): s; case var tk: unexpected(tk); });
							 | 
						||
| 
								 | 
							
											case "Operator":
							 | 
						||
| 
								 | 
							
												ensure(TOp("="));
							 | 
						||
| 
								 | 
							
												AOperator(switch( token() ) { case TString(s): s; case var tk: unexpected(tk); });
							 | 
						||
| 
								 | 
							
											case var attr:
							 | 
						||
| 
								 | 
							
												error("Unsupported attribute " + attr);
							 | 
						||
| 
								 | 
							
												null;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											attrs.push(attr);
							 | 
						||
| 
								 | 
							
											if( !maybe(TComma) ) break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										ensure(TBkClose);
							 | 
						||
| 
								 | 
							
										return attrs;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function type() : Type {
							 | 
						||
| 
								 | 
							
										var id = ident();
							 | 
						||
| 
								 | 
							
										var t = switch( id ) {
							 | 
						||
| 
								 | 
							
										case "void": TVoid;
							 | 
						||
| 
								 | 
							
										case "float": TFloat;
							 | 
						||
| 
								 | 
							
										case "double": TDouble;
							 | 
						||
| 
								 | 
							
										case "long", "int": TInt; // long ensures 32 bits
							 | 
						||
| 
								 | 
							
										case "short": TShort;
							 | 
						||
| 
								 | 
							
										case "boolean", "bool": TBool;
							 | 
						||
| 
								 | 
							
										case "any": TAny;
							 | 
						||
| 
								 | 
							
										case "VoidPtr": TVoidPtr;
							 | 
						||
| 
								 | 
							
										default: TCustom(id);
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
										if( maybe(TBkOpen) ) {
							 | 
						||
| 
								 | 
							
											ensure(TBkClose);
							 | 
						||
| 
								 | 
							
											t = TArray(t);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return t;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function makePos( pmin : Int ) {
							 | 
						||
| 
								 | 
							
										return { file : fileName, line : line, pos : pmin };
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function parseField() : Field {
							 | 
						||
| 
								 | 
							
										var attr = attributes();
							 | 
						||
| 
								 | 
							
										var pmin = this.pos;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if( maybe(TId("attribute")) ) {
							 | 
						||
| 
								 | 
							
											var t = type();
							 | 
						||
| 
								 | 
							
											var name = ident();
							 | 
						||
| 
								 | 
							
											ensure(TSemicolon);
							 | 
						||
| 
								 | 
							
											return { name : name, kind : FAttribute({ t : t, attr : attr }), pos : makePos(pmin) };
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if( maybe(TId("const")) ) {
							 | 
						||
| 
								 | 
							
											var type = type();
							 | 
						||
| 
								 | 
							
											var name = ident();
							 | 
						||
| 
								 | 
							
											ensure(TOp("="));
							 | 
						||
| 
								 | 
							
											var value = tokenString(token());
							 | 
						||
| 
								 | 
							
											ensure(TSemicolon);
							 | 
						||
| 
								 | 
							
											return { name: name, kind : DConst(name, type, value), pos : makePos(pmin) };
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										var tret = type();
							 | 
						||
| 
								 | 
							
										var name = ident();
							 | 
						||
| 
								 | 
							
										ensure(TPOpen);
							 | 
						||
| 
								 | 
							
										var args = [];
							 | 
						||
| 
								 | 
							
										if( !maybe(TPClose) ) {
							 | 
						||
| 
								 | 
							
											while( true ) {
							 | 
						||
| 
								 | 
							
												var attr = attributes();
							 | 
						||
| 
								 | 
							
												var opt = maybe(TId("optional"));
							 | 
						||
| 
								 | 
							
												var t = type();
							 | 
						||
| 
								 | 
							
												var name = ident();
							 | 
						||
| 
								 | 
							
												args.push({ name : name, t : { t : t, attr : attr }, opt : opt });
							 | 
						||
| 
								 | 
							
												switch( token() ) {
							 | 
						||
| 
								 | 
							
												case TPClose:
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												case TComma:
							 | 
						||
| 
								 | 
							
													continue;
							 | 
						||
| 
								 | 
							
												case var tk:
							 | 
						||
| 
								 | 
							
													unexpected(tk);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										ensure(TSemicolon);
							 | 
						||
| 
								 | 
							
										return { name : name, kind : FMethod(args, { attr : attr, t : tret }), pos : makePos(pmin) };
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// --- Lexing
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function invalidChar(c:Int) {
							 | 
						||
| 
								 | 
							
										error("Invalid char "+c+"("+String.fromCharCode(c)+")");
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function error( msg : String ) {
							 | 
						||
| 
								 | 
							
										throw msg+" line "+line;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function unexpected( tk ) : Dynamic {
							 | 
						||
| 
								 | 
							
										error("Unexpected " + tokenString(tk));
							 | 
						||
| 
								 | 
							
										return null;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function tokenString( tk ) {
							 | 
						||
| 
								 | 
							
										return switch( tk ) {
							 | 
						||
| 
								 | 
							
										case TEof: "<eof>";
							 | 
						||
| 
								 | 
							
										case TId(id): id;
							 | 
						||
| 
								 | 
							
										case TPOpen: "(";
							 | 
						||
| 
								 | 
							
										case TPClose: ")";
							 | 
						||
| 
								 | 
							
										case TBkOpen: "[";
							 | 
						||
| 
								 | 
							
										case TBkClose: "]";
							 | 
						||
| 
								 | 
							
										case TBrOpen: "{";
							 | 
						||
| 
								 | 
							
										case TBrClose: "}";
							 | 
						||
| 
								 | 
							
										case TComma: ",";
							 | 
						||
| 
								 | 
							
										case TSemicolon: ";";
							 | 
						||
| 
								 | 
							
										case TOp(op): op;
							 | 
						||
| 
								 | 
							
										case TString(str): '"' + str + '"';
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline function push(tk) {
							 | 
						||
| 
								 | 
							
										tokens.push(tk);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function ensure(tk) {
							 | 
						||
| 
								 | 
							
										var t = token();
							 | 
						||
| 
								 | 
							
										if( t != tk && !std.Type.enumEq(t,tk) ) unexpected(t);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function maybe(tk) {
							 | 
						||
| 
								 | 
							
										var t = token();
							 | 
						||
| 
								 | 
							
										if( t == tk || std.Type.enumEq(t,tk) )
							 | 
						||
| 
								 | 
							
											return true;
							 | 
						||
| 
								 | 
							
										push(t);
							 | 
						||
| 
								 | 
							
										return false;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function ident() {
							 | 
						||
| 
								 | 
							
										var tk = token();
							 | 
						||
| 
								 | 
							
										switch( tk ) {
							 | 
						||
| 
								 | 
							
										case TId(id): return id;
							 | 
						||
| 
								 | 
							
										default:
							 | 
						||
| 
								 | 
							
											unexpected(tk);
							 | 
						||
| 
								 | 
							
											return null;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function readChar() {
							 | 
						||
| 
								 | 
							
										pos++;
							 | 
						||
| 
								 | 
							
										return try input.readByte() catch( e : Dynamic ) 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function token() : Token {
							 | 
						||
| 
								 | 
							
										if( tokens.length > 0 )
							 | 
						||
| 
								 | 
							
											return tokens.shift();
							 | 
						||
| 
								 | 
							
										var char;
							 | 
						||
| 
								 | 
							
										if( this.char < 0 )
							 | 
						||
| 
								 | 
							
											char = readChar();
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											char = this.char;
							 | 
						||
| 
								 | 
							
											this.char = -1;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										while( true ) {
							 | 
						||
| 
								 | 
							
											switch( char ) {
							 | 
						||
| 
								 | 
							
											case 0: return TEof;
							 | 
						||
| 
								 | 
							
											case 32,9,13: // space, tab, CR
							 | 
						||
| 
								 | 
							
											case 10: line++; // LF
							 | 
						||
| 
								 | 
							
								/*			case 48,49,50,51,52,53,54,55,56,57: // 0...9
							 | 
						||
| 
								 | 
							
												var n = (char - 48) * 1.0;
							 | 
						||
| 
								 | 
							
												var exp = 0.;
							 | 
						||
| 
								 | 
							
												while( true ) {
							 | 
						||
| 
								 | 
							
													char = readChar();
							 | 
						||
| 
								 | 
							
													exp *= 10;
							 | 
						||
| 
								 | 
							
													switch( char ) {
							 | 
						||
| 
								 | 
							
													case 48,49,50,51,52,53,54,55,56,57:
							 | 
						||
| 
								 | 
							
														n = n * 10 + (char - 48);
							 | 
						||
| 
								 | 
							
													case 46:
							 | 
						||
| 
								 | 
							
														if( exp > 0 ) {
							 | 
						||
| 
								 | 
							
															// in case of '...'
							 | 
						||
| 
								 | 
							
															if( exp == 10 && readChar() == 46 ) {
							 | 
						||
| 
								 | 
							
																push(TOp("..."));
							 | 
						||
| 
								 | 
							
																var i = Std.int(n);
							 | 
						||
| 
								 | 
							
																return TConst( (i == n) ? CInt(i) : CFloat(n) );
							 | 
						||
| 
								 | 
							
															}
							 | 
						||
| 
								 | 
							
															invalidChar(char);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														exp = 1.;
							 | 
						||
| 
								 | 
							
													case 120: // x
							 | 
						||
| 
								 | 
							
														if( n > 0 || exp > 0 )
							 | 
						||
| 
								 | 
							
															invalidChar(char);
							 | 
						||
| 
								 | 
							
														// read hexa
							 | 
						||
| 
								 | 
							
														#if haxe3
							 | 
						||
| 
								 | 
							
														var n = 0;
							 | 
						||
| 
								 | 
							
														while( true ) {
							 | 
						||
| 
								 | 
							
															char = readChar();
							 | 
						||
| 
								 | 
							
															switch( char ) {
							 | 
						||
| 
								 | 
							
															case 48,49,50,51,52,53,54,55,56,57: // 0-9
							 | 
						||
| 
								 | 
							
																n = (n << 4) + char - 48;
							 | 
						||
| 
								 | 
							
															case 65,66,67,68,69,70: // A-F
							 | 
						||
| 
								 | 
							
																n = (n << 4) + (char - 55);
							 | 
						||
| 
								 | 
							
															case 97,98,99,100,101,102: // a-f
							 | 
						||
| 
								 | 
							
																n = (n << 4) + (char - 87);
							 | 
						||
| 
								 | 
							
															default:
							 | 
						||
| 
								 | 
							
																this.char = char;
							 | 
						||
| 
								 | 
							
																return TConst(CInt(n));
							 | 
						||
| 
								 | 
							
															}
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														#else
							 | 
						||
| 
								 | 
							
														var n = haxe.Int32.ofInt(0);
							 | 
						||
| 
								 | 
							
														while( true ) {
							 | 
						||
| 
								 | 
							
															char = readChar();
							 | 
						||
| 
								 | 
							
															switch( char ) {
							 | 
						||
| 
								 | 
							
															case 48,49,50,51,52,53,54,55,56,57: // 0-9
							 | 
						||
| 
								 | 
							
																n = haxe.Int32.add(haxe.Int32.shl(n,4), cast (char - 48));
							 | 
						||
| 
								 | 
							
															case 65,66,67,68,69,70: // A-F
							 | 
						||
| 
								 | 
							
																n = haxe.Int32.add(haxe.Int32.shl(n,4), cast (char - 55));
							 | 
						||
| 
								 | 
							
															case 97,98,99,100,101,102: // a-f
							 | 
						||
| 
								 | 
							
																n = haxe.Int32.add(haxe.Int32.shl(n,4), cast (char - 87));
							 | 
						||
| 
								 | 
							
															default:
							 | 
						||
| 
								 | 
							
																this.char = char;
							 | 
						||
| 
								 | 
							
																// we allow to parse hexadecimal Int32 in Neko, but when the value will be
							 | 
						||
| 
								 | 
							
																// evaluated by Interpreter, a failure will occur if no Int32 operation is
							 | 
						||
| 
								 | 
							
																// performed
							 | 
						||
| 
								 | 
							
																var v = try CInt(haxe.Int32.toInt(n)) catch( e : Dynamic ) CInt32(n);
							 | 
						||
| 
								 | 
							
																return TConst(v);
							 | 
						||
| 
								 | 
							
															}
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														#end
							 | 
						||
| 
								 | 
							
													default:
							 | 
						||
| 
								 | 
							
														this.char = char;
							 | 
						||
| 
								 | 
							
														var i = Std.int(n);
							 | 
						||
| 
								 | 
							
														return TConst( (exp > 0) ? CFloat(n * 10 / exp) : ((i == n) ? CInt(i) : CFloat(n)) );
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}*/
							 | 
						||
| 
								 | 
							
											case 59: return TSemicolon;
							 | 
						||
| 
								 | 
							
											case 40: return TPOpen;
							 | 
						||
| 
								 | 
							
											case 41: return TPClose;
							 | 
						||
| 
								 | 
							
											case 44: return TComma;
							 | 
						||
| 
								 | 
							
								/*			case 46:
							 | 
						||
| 
								 | 
							
												char = readChar();
							 | 
						||
| 
								 | 
							
												switch( char ) {
							 | 
						||
| 
								 | 
							
												case 48,49,50,51,52,53,54,55,56,57:
							 | 
						||
| 
								 | 
							
													var n = char - 48;
							 | 
						||
| 
								 | 
							
													var exp = 1;
							 | 
						||
| 
								 | 
							
													while( true ) {
							 | 
						||
| 
								 | 
							
														char = readChar();
							 | 
						||
| 
								 | 
							
														exp *= 10;
							 | 
						||
| 
								 | 
							
														switch( char ) {
							 | 
						||
| 
								 | 
							
														case 48,49,50,51,52,53,54,55,56,57:
							 | 
						||
| 
								 | 
							
															n = n * 10 + (char - 48);
							 | 
						||
| 
								 | 
							
														default:
							 | 
						||
| 
								 | 
							
															this.char = char;
							 | 
						||
| 
								 | 
							
															return TConst( CFloat(n/exp) );
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												case 46:
							 | 
						||
| 
								 | 
							
													char = readChar();
							 | 
						||
| 
								 | 
							
													if( char != 46 )
							 | 
						||
| 
								 | 
							
														invalidChar(char);
							 | 
						||
| 
								 | 
							
													return TOp("...");
							 | 
						||
| 
								 | 
							
												default:
							 | 
						||
| 
								 | 
							
													this.char = char;
							 | 
						||
| 
								 | 
							
													return TDot;
							 | 
						||
| 
								 | 
							
												}*/
							 | 
						||
| 
								 | 
							
											case 123: return TBrOpen;
							 | 
						||
| 
								 | 
							
											case 125: return TBrClose;
							 | 
						||
| 
								 | 
							
											case 91: return TBkOpen;
							 | 
						||
| 
								 | 
							
											case 93: return TBkClose;
							 | 
						||
| 
								 | 
							
											case 39: return TString(readString(39));
							 | 
						||
| 
								 | 
							
											case 34: return TString(readString(34));
							 | 
						||
| 
								 | 
							
								//			case 63: return TQuestion;
							 | 
						||
| 
								 | 
							
								//			case 58: return TDoubleDot;
							 | 
						||
| 
								 | 
							
											case '='.code:
							 | 
						||
| 
								 | 
							
												char = readChar();
							 | 
						||
| 
								 | 
							
												if( char == '='.code )
							 | 
						||
| 
								 | 
							
													return TOp("==");
							 | 
						||
| 
								 | 
							
												else if ( char == '>'.code )
							 | 
						||
| 
								 | 
							
													return TOp("=>");
							 | 
						||
| 
								 | 
							
												this.char = char;
							 | 
						||
| 
								 | 
							
												return TOp("=");
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
												if( ops[char] ) {
							 | 
						||
| 
								 | 
							
													var op = String.fromCharCode(char);
							 | 
						||
| 
								 | 
							
													var prev = -1;
							 | 
						||
| 
								 | 
							
													while( true ) {
							 | 
						||
| 
								 | 
							
														char = readChar();
							 | 
						||
| 
								 | 
							
														if( !ops[char] || prev == '='.code ) {
							 | 
						||
| 
								 | 
							
															if( op.charCodeAt(0) == '/'.code )
							 | 
						||
| 
								 | 
							
																return tokenComment(op,char);
							 | 
						||
| 
								 | 
							
															this.char = char;
							 | 
						||
| 
								 | 
							
															return TOp(op);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														prev = char;
							 | 
						||
| 
								 | 
							
														op += String.fromCharCode(char);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												if( idents[char] ) {
							 | 
						||
| 
								 | 
							
													var id = String.fromCharCode(char);
							 | 
						||
| 
								 | 
							
													while( true ) {
							 | 
						||
| 
								 | 
							
														char = readChar();
							 | 
						||
| 
								 | 
							
														if( !idents[char] ) {
							 | 
						||
| 
								 | 
							
															this.char = char;
							 | 
						||
| 
								 | 
							
															return TId(id);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														id += String.fromCharCode(char);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												invalidChar(char);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											char = readChar();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return null;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function tokenComment( op : String, char : Int ) {
							 | 
						||
| 
								 | 
							
										var c = op.charCodeAt(1);
							 | 
						||
| 
								 | 
							
										var s = input;
							 | 
						||
| 
								 | 
							
										if( c == '/'.code ) { // comment
							 | 
						||
| 
								 | 
							
											try {
							 | 
						||
| 
								 | 
							
												while( char != '\r'.code && char != '\n'.code ) {
							 | 
						||
| 
								 | 
							
													pos++;
							 | 
						||
| 
								 | 
							
													char = s.readByte();
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												this.char = char;
							 | 
						||
| 
								 | 
							
											} catch( e : Dynamic ) {
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return token();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if( c == '*'.code ) { /* comment */
							 | 
						||
| 
								 | 
							
											var old = line;
							 | 
						||
| 
								 | 
							
											if( op == "/**/" ) {
							 | 
						||
| 
								 | 
							
												this.char = char;
							 | 
						||
| 
								 | 
							
												return token();
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											try {
							 | 
						||
| 
								 | 
							
												while( true ) {
							 | 
						||
| 
								 | 
							
													while( char != '*'.code ) {
							 | 
						||
| 
								 | 
							
														if( char == '\n'.code ) line++;
							 | 
						||
| 
								 | 
							
														pos++;
							 | 
						||
| 
								 | 
							
														char = s.readByte();
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													pos++;
							 | 
						||
| 
								 | 
							
													char = s.readByte();
							 | 
						||
| 
								 | 
							
													if( char == '/'.code )
							 | 
						||
| 
								 | 
							
														break;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											} catch( e : Dynamic ) {
							 | 
						||
| 
								 | 
							
												line = old;
							 | 
						||
| 
								 | 
							
												error("Unterminated comment");
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return token();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										this.char = char;
							 | 
						||
| 
								 | 
							
										return TOp(op);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function readString( until ) {
							 | 
						||
| 
								 | 
							
										var c = 0;
							 | 
						||
| 
								 | 
							
										var b = new haxe.io.BytesOutput();
							 | 
						||
| 
								 | 
							
										var esc = false;
							 | 
						||
| 
								 | 
							
										var old = line;
							 | 
						||
| 
								 | 
							
										var s = input;
							 | 
						||
| 
								 | 
							
										while( true ) {
							 | 
						||
| 
								 | 
							
											try {
							 | 
						||
| 
								 | 
							
												pos++;
							 | 
						||
| 
								 | 
							
												c = s.readByte();
							 | 
						||
| 
								 | 
							
											} catch( e : Dynamic ) {
							 | 
						||
| 
								 | 
							
												line = old;
							 | 
						||
| 
								 | 
							
												error("Unterminated string");
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if( esc ) {
							 | 
						||
| 
								 | 
							
												esc = false;
							 | 
						||
| 
								 | 
							
												switch( c ) {
							 | 
						||
| 
								 | 
							
												case 'n'.code: b.writeByte(10);
							 | 
						||
| 
								 | 
							
												case 'r'.code: b.writeByte(13);
							 | 
						||
| 
								 | 
							
												case 't'.code: b.writeByte(9);
							 | 
						||
| 
								 | 
							
												case "'".code, '"'.code, '\\'.code: b.writeByte(c);
							 | 
						||
| 
								 | 
							
												case '/'.code: b.writeByte(c);
							 | 
						||
| 
								 | 
							
												default: invalidChar(c);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											} else if( c == 92 )
							 | 
						||
| 
								 | 
							
												esc = true;
							 | 
						||
| 
								 | 
							
											else if( c == until )
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
											else {
							 | 
						||
| 
								 | 
							
												if( c == 10 ) line++;
							 | 
						||
| 
								 | 
							
												b.writeByte(c);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return b.getBytes().toString();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 |