216 lines
7.2 KiB
Plaintext
216 lines
7.2 KiB
Plaintext
|
obj
|
||
|
kw : "kwdefs"
|
||
|
token : "tokenrdr"
|
||
|
bt : "bintree"
|
||
|
st : "symbols"
|
||
|
|
||
|
dat
|
||
|
pass byte 0
|
||
|
insideDAT byte 0
|
||
|
ignoreUndefined byte 0
|
||
|
evalSuccess byte 0
|
||
|
pGlobalLabel word 0
|
||
|
|
||
|
pub set_Pass( p )
|
||
|
pass := p
|
||
|
|
||
|
pub get_Pass
|
||
|
return pass
|
||
|
|
||
|
pub EnteringDat
|
||
|
insideDAT~~
|
||
|
|
||
|
pub LeavingDat
|
||
|
insideDAT~
|
||
|
|
||
|
pub Succeeded
|
||
|
return evalSuccess
|
||
|
|
||
|
pub TryToEvaluateExpression( _pGlobalLabel )
|
||
|
{{
|
||
|
}}
|
||
|
pGlobalLabel := _pGlobalLabel
|
||
|
ignoreUndefined~~
|
||
|
evalSuccess~~
|
||
|
return Evaluate( 13 )
|
||
|
|
||
|
pub EvaluateExpression( _pGlobalLabel )
|
||
|
pGlobalLabel := _pGlobalLabel
|
||
|
ignoreUndefined~
|
||
|
evalSuccess~~
|
||
|
return Evaluate( 13 )
|
||
|
|
||
|
pri Evaluate( rbp ) | prec, lbp, t
|
||
|
prec := token.GetPrecedence
|
||
|
|
||
|
if token.AdvanceIf( kw#kAT )
|
||
|
result := EvaluateSymbol( true )
|
||
|
elseif (token.IsUnaryOp and not token.IsPostfixOp) or token.Type == kw#kMINUS
|
||
|
t := token.Type
|
||
|
token.Advance
|
||
|
result := EvaluateUnary( t, prec )
|
||
|
elseif token.AdvanceIf( kw#kLPAREN )
|
||
|
result := Evaluate( 13 )
|
||
|
token.Eat( kw#kRPAREN )
|
||
|
elseif token.IsIntLiteral or token.IsFloatLiteral
|
||
|
result := token.Value
|
||
|
token.Advance
|
||
|
elseif token.IsReg
|
||
|
result := $1f0 + token.GetReg
|
||
|
token.Advance
|
||
|
else
|
||
|
result := EvaluateSymbol( false )
|
||
|
|
||
|
repeat
|
||
|
lbp := token.GetPrecedence
|
||
|
|
||
|
if rbp =< lbp
|
||
|
quit
|
||
|
|
||
|
t := token.Type
|
||
|
token.Advance
|
||
|
result := EvaluateBinary( t, result, Evaluate( lbp ) )
|
||
|
|
||
|
pri EvaluateSymbol( takeAddress ) | p, t, pObj, cogx4, pLocalLabels
|
||
|
{{
|
||
|
CON symbols evaluate as their defined values, as do OBJ#constants.
|
||
|
DAT symbols evaluate differently depending on context.
|
||
|
}}
|
||
|
if byte[token.Text] == ":" ' local label?
|
||
|
ifnot pGlobalLabel
|
||
|
abort string("Unknown local label(1)")
|
||
|
|
||
|
p := pGlobalLabel ' Search local label list for current token.
|
||
|
repeat
|
||
|
ifnot p := bt.PeekW( p + 6 ) ' p points to string part of local label
|
||
|
if ignoreUndefined
|
||
|
evalSuccess~
|
||
|
token.Advance
|
||
|
return -1 ' dummy value
|
||
|
abort string("Unknown local label(2)")
|
||
|
if strcomp( p, token.Text )
|
||
|
quit
|
||
|
p += strsize(p) + 1 ' Increment p past string part to data part
|
||
|
' On exit, we've found the local label.
|
||
|
p += strsize(p) + 1 ' Increment p past string part to data part
|
||
|
|
||
|
else
|
||
|
p := st.SymbolLookup( token.Text )
|
||
|
ifnot p
|
||
|
if ignoreUndefined
|
||
|
evalSuccess~
|
||
|
token.Advance
|
||
|
return -1
|
||
|
abort string("Unknown symbol")
|
||
|
|
||
|
t := byte[p]
|
||
|
|
||
|
if t == st#kINT_CON_SYMBOL or t == st#kFLOAT_CON_SYMBOL or t == st#kBUILTIN_INT_SYMBOL or t == st#kBUILTIN_FLOAT_SYMBOL
|
||
|
' TODO: should handle floats differently
|
||
|
if takeAddress
|
||
|
abort string("Can't take address of CON symbol")
|
||
|
token.Advance
|
||
|
return bt.PeekL( p+1 )
|
||
|
if t == st#kUNDEFINED_CON_SYMBOL
|
||
|
if ignoreUndefined
|
||
|
evalSuccess~
|
||
|
token.Advance
|
||
|
return -1 ' dummy value
|
||
|
abort string("Undefined CON symbol")
|
||
|
if t == st#kOBJ_SYMBOL
|
||
|
if takeAddress
|
||
|
abort string("Can't take address of OBJ symbol")
|
||
|
token.Advance
|
||
|
p := bt.PeekW( p+1 )
|
||
|
pObj := bt.PeekW( p + strsize(p) + 2 )
|
||
|
token.Eat( kw#kOCTOTHORP )
|
||
|
ifnot p := bt.FindInTable( token.Text, pObj )
|
||
|
abort string("CON symbol unknown in sub-object")
|
||
|
't := byte[p] -- at this point, t should be either kINT_CON_SYMBOL or kFLOAT_CON_SYMBOL
|
||
|
' TODO: should handle floats differently
|
||
|
token.Advance
|
||
|
return bt.PeekL( p+1 )
|
||
|
|
||
|
if t == st#kDAT_SYMBOL
|
||
|
if pass == 1
|
||
|
if ignoreUndefined
|
||
|
evalSuccess~
|
||
|
token.Advance
|
||
|
return -1 ' dummy value
|
||
|
if takeAddress
|
||
|
abort string("Can't take address of DAT symbol in pass 1")
|
||
|
if not insideDAT or takeAddress
|
||
|
token.Advance
|
||
|
return bt.PeekW( p+2 )
|
||
|
|
||
|
cogx4 := bt.PeekW( p+4 )
|
||
|
if cogx4 & 3
|
||
|
abort string("Address is not long")
|
||
|
token.Advance
|
||
|
return cogx4 >> 2
|
||
|
|
||
|
abort string("Invalid symbol in constant expression")
|
||
|
|
||
|
pri EvaluateUnary( t, prec )
|
||
|
{{
|
||
|
|
||
|
}}
|
||
|
result := Evaluate( prec )
|
||
|
case t & $ff
|
||
|
$ed: -result
|
||
|
$e7: !result
|
||
|
$ff: not result
|
||
|
$f3: |<result
|
||
|
$f1: >|result
|
||
|
$f8: ^^result
|
||
|
$e9: ||result
|
||
|
other: abort string("Syntax error in constant expression(1)")
|
||
|
|
||
|
pri EvaluateBinary( t, a, b )
|
||
|
case t & $ff
|
||
|
$ec: return a + b
|
||
|
$ed: return a - b
|
||
|
$f4: return a * b
|
||
|
$f6: return a / b
|
||
|
$f5: return a ** b
|
||
|
$f7: return a // b
|
||
|
$e0: return a -> b
|
||
|
$e1: return a <- b
|
||
|
$e2: return a >> b
|
||
|
$e3: return a << b
|
||
|
$ee: return a ~> b
|
||
|
$ef: return a >< b
|
||
|
$e8: return a & b
|
||
|
$ea: return a | b
|
||
|
$eb: return a ^ b
|
||
|
$e4: return a #> b
|
||
|
$e5: return a <# b
|
||
|
$f9: return a < b
|
||
|
$fa: return a > b
|
||
|
$fc: return a == b
|
||
|
$fb: return a <> b
|
||
|
$fd: return a =< b
|
||
|
$fe: return a => b
|
||
|
$f0: return a and b
|
||
|
$f2: return a or b
|
||
|
other: abort string("Syntax error in constant expression(2)")
|
||
|
|
||
|
{{
|
||
|
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. |
|
||
|
+------------------------------------------------------------------------------------------------------------------------------+
|
||
|
}}
|
||
|
|