obj sxfs: "isxfs" kw: "kwdefs" bt: "bintree" dat long filestuff byte 0[sxfs#SIZEOFFILESTUFF] pub Open( pFilename ) if \sxfs.Open( @filestuff, pFilename, "R" ) <> 0 abort string("can't open file") Advance ' prime the pump pub Close sxfs.Close( @filestuff ) con MAXTOKENLENGTH = 32 dat tokenType long 0 tokenValue long 0 tokenLineNumber word 0 tokenCol word 0 tokenText byte 0[MAXTOKENLENGTH+1] pub Text return @tokenText pub Type return tokenType pub Column return tokenCol pub LineNumber return tokenLineNumber pub Value return tokenValue pub AdvanceIf( t ) {{ If current token's type is t, advance and return true; otherwise return false without advancing. t should be one of the specific token types, not a generic type like kCOND. }} if tokenType <> t return false Advance return true pub Eat( t ) {{ Like Advance, but asserts that the soon-to-be-previous token's type is t. t should be one of the specific token types, not a generic type like kCOND. }} if tokenType <> t abort string("Syntax error (unexpected)") Advance pub Advance tokenType := ReadLong tokenLineNumber := ReadWord tokenCol := ReadWord if tokenType == kw#kINTLITERAL or tokenType == kw#kFLOATLITERAL sxfs.Read( @filestuff, @tokenValue, 4 ) else ReadString( @tokenText, MAXTOKENLENGTH ) pub IsId {{ Returns non-zero (not necessarily -1) if token is a plain old identifier. Returns 0 otherwise. }} return tokenType & kw#kID pub IsIntLiteral {{ Returns non-zero (not necessarily -1) if token is an int literal. Returns 0 otherwise. }} return tokenType & kw#kINTLITERAL pub IsFloatLiteral {{ Returns non-zero (not necessarily -1) if token is an float literal. Returns 0 otherwise. }} return tokenType & kw#kFLOATLITERAL pub IsUnaryOp {{ Returns non-zero (not necessarily -1) if token is a unary operator. Returns 0 otherwise. }} return tokenType & kw#kUNARY pub IsBinaryOp {{ Returns non-zero (not necessarily -1) if token is a binary operator. Returns 0 otherwise. }} return ( tokenType & constant(kw#kUNARY|kw#kBINARY) ) == kw#kBINARY pub IsPostfixOp {{ Returns non-zero (not necessarily -1) if token is a postfix operator. Returns 0 otherwise. }} return ( tokenType & constant(kw#kUNARY|kw#kPOSTFIX) ) == constant(kw#kUNARY|kw#kPOSTFIX) pub IsAssignmentOp {{ Returns non-zero (not necessarily -1) if token is an assignment operator. Returns 0 otherwise. }} return tokenType & kw#kASSIGNMENT pub GetPrecedence {{ If token is an operator, returns its precedence. If token isn't, returns 13. }} if tokenType & constant( kw#kBINARY | kw#kUNARY ) return (tokenType >> 16) & $0f else return 13 pub GetSpinOpcode {{ If token is an operator or a statement function, returns its Spin opcode. If token isn't, returns nonsense. }} return tokenType & $ff pub GetSpinOpcode2 {{ If token is a postfix operator, returns its alternate Spin opcode. If token isn't, returns nonsense. }} return (tokenType >> 8) & $ff pub IsPasm {{ Returns non-zero (not necessarily -1) if token is a PASM mnemonic. Returns 0 otherwise. }} return tokenType & kw#kPASM pub GetPasmOp {{ If token is a PASM mnemonic, return its PASM opcode. }} return tokenType << 16 pub GetPasmDS {{ If token is a PASM mnemonic, return its DS information. }} return (tokenType >> 16) & 3 pub IsCond {{ Returns non-zero (not necessarily -1) if token is a PASM condition code (e.g., IF_A). Returns 0 otherwise. }} return tokenType & kw#kCOND pub GetCond {{ Returns condition bits if token is a PASM condition code. }} return tokenType & $0f pub IsEffect {{ Returns non-zero (not necessarily -1) if token is a PASM effect (e.g., WC). Returns 0 otherwise. }} return tokenType & kw#kEFFECT pub GetEffect {{ Returns effect bits if token is a PASM effect. }} return tokenType & $0f pub IsReg {{ Returns non-zero (not necessarily -1) if token is a special register (e.g., PHSA). Returns 0 otherwise. }} return kw#kPAR =< tokenType and tokenType =< kw#kVSCL pub GetReg {{ Returns register# if token is a special register. }} return tokenType - kw#kPAR pub IsBlockDesignator {{ Returns true if token is a block designator (e.g., DAT). }} return kw#kCON =< tokenType and tokenType =< kw#kVAR pub IsSize {{ Returns true if token is BYTE, WORD, or LONG. }} return kw#kBYTE =< tokenType and tokenType =< kw#kLONG pub IsStmtFn {{ Returns non-zero (not necessarily -1) if token is a "statement function" (e.g. BYTEMOVE, WAITCNT). Returns 0 otherwise. }} return tokenType & kw#kSTMTFN pub GetNumArgs {{ Returns #args if token is a "statement function". }} return (tokenType >> 8) & 3 pub IsIntrinsic {{ Returns non-zero (not necessarily -1) if token is an intrinsic (e.g., COGNEW, LOOKUP). Returns 0 otherwise. }} return tokenType & kw#kINTRINSIC pri ReadString( p, MAXLENGTH ) | ch repeat MAXLENGTH + 1 ch := ReadByte if "a" =< ch and ch =< "z" ch -= constant("a" - "A") ifnot byte[p++] := ch return abort string("ReadString: string too long") pri ReadByte : ch sxfs.Read( @filestuff, @ch, 1 ) pri ReadWord return ReadByte + (ReadByte << 8) pri ReadLong return ReadByte + (ReadByte << 8) + (ReadByte << 16) + (ReadByte << 24) {{ Copyright (c) 2009 Michael Park +------------------------------------------------------------------------------------------------------------------------------+ | TERMS OF USE: MIT License | +------------------------------------------------------------------------------------------------------------------------------+ |Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | |files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | |modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| |is furnished to do so, subject to the following conditions: | | | |The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| | | |THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | |WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | |COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | +------------------------------------------------------------------------------------------------------------------------------+ }}