Update NTSL from /tg/.

This commit is contained in:
Rob Nelson
2013-08-14 15:42:23 -07:00
parent 3fab835417
commit 153871400a
16 changed files with 603 additions and 361 deletions

View File

@@ -180,12 +180,18 @@
- <ParseParenExpression()>
- <ParseParamExpression()>
*/
ParseExpression(list/end=list(/token/end), list/ErrChars=list("{", "}"))
ParseExpression(list/end=list(/token/end), list/ErrChars=list("{", "}"), check_functions = 0)
var/stack
opr=new
val=new
src.expecting=VALUE
var/loop = 0
for()
loop++
if(loop > 800)
errors+=new/scriptError("Too many nested tokens.")
return
if(EndOfExpression(end))
break
if(istype(curToken, /token/symbol) && ErrChars.Find(curToken.value))
@@ -206,6 +212,7 @@
NextToken()
continue
val.Push(ParseParenExpression())
else if(istype(curToken, /token/symbol)) //Operator found.
var/node/expression/operator/curOperator //Figure out whether it is unary or binary and get a new instance.
if(src.expecting==OPERATOR)
@@ -226,16 +233,24 @@
continue
opr.Push(curOperator)
src.expecting=VALUE
else if(ntok && ntok.value=="(" && istype(ntok, /token/symbol)\
&& istype(curToken, /token/word)) //Parse function call
var/token/preToken=curToken
var/old_expect=src.expecting
var/fex=ParseFunctionExpression()
if(old_expect!=VALUE)
errors+=new/scriptError/ExpectedToken("operator", preToken)
NextToken()
continue
val.Push(fex)
if(!check_functions)
var/token/preToken=curToken
var/old_expect=src.expecting
var/fex=ParseFunctionExpression()
if(old_expect!=VALUE)
errors+=new/scriptError/ExpectedToken("operator", preToken)
NextToken()
continue
val.Push(fex)
else
errors+=new/scriptError/ParameterFunction(curToken)
break
else if(istype(curToken, /token/keyword)) //inline keywords
var/n_Keyword/kw=options.keywords[curToken.value]
kw=new kw(inline=1)
@@ -244,6 +259,7 @@
return
else
errors+=new/scriptError/BadToken(curToken)
else if(istype(curToken, /token/end)) //semicolon found where it wasn't expected
errors+=new/scriptError/BadToken(curToken)
NextToken()
@@ -255,6 +271,7 @@
continue
val.Push(GetExpression(curToken))
src.expecting=OPERATOR
NextToken()
while(opr.Top()) Reduce(opr, val) //Reduce the value stack completely
@@ -280,12 +297,16 @@
for()
loops++
if(loops>=1000)
CRASH("Something TERRIBLE has gone wrong in ParseFunctionExpression ;__;")
if(loops>=800)
errors += new/scriptError("Too many nested expressions.")
break
//CRASH("Something TERRIBLE has gone wrong in ParseFunctionExpression ;__;")
if(istype(curToken, /token/symbol) && curToken.value==")")
return exp
exp.parameters+=ParseParamExpression()
if(errors.len)
return exp
if(curToken.value==","&&istype(curToken, /token/symbol))NextToken() //skip comma
if(istype(curToken, /token/end)) //Prevents infinite loop...
errors+=new/scriptError/ExpectedToken(")")
@@ -310,5 +331,6 @@
See Also:
- <ParseExpression()>
*/
ParseParamExpression()
return ParseExpression(list(",", ")"))
ParseParamExpression(var/check_functions = 0)
var/cf = check_functions
return ParseExpression(list(",", ")"), check_functions = cf)

View File

@@ -51,9 +51,9 @@ var/const/Represents a special statement in the code triggered by a keyword.
kwReturn
Parse(n_Parser/nS_Parser/parser)
.=KW_PASS
if(istype(parser.curBlock, /node/BlockDefinition/GlobalBlock))
parser.errors+=new/scriptError/BadReturn(parser.curToken)
. = KW_WARN
if(istype(parser.curBlock, /node/BlockDefinition/GlobalBlock)) // Exit out of the program by setting the tokens list size to the same as index.
parser.tokens.len = parser.index
return
var/node/statement/ReturnStatement/stmt=new
parser.NextToken() //skip 'return' token
stmt.value=parser.ParseExpression()
@@ -73,6 +73,31 @@ var/const/Represents a special statement in the code triggered by a keyword.
stmt.block=new
parser.AddBlock(stmt.block)
kwElseIf
Parse(n_Parser/nS_Parser/parser)
.=KW_PASS
var/list/L=parser.curBlock.statements
var/node/statement/IfStatement/ifstmt
if(L && L.len)
ifstmt = L[L.len] //Get the last statement in the current block
if(!ifstmt || !istype(ifstmt) || ifstmt.else_if)
parser.errors += new/scriptError/ExpectedToken("if statement", parser.curToken)
return KW_FAIL
var/node/statement/IfStatement/ElseIf/stmt = new
parser.NextToken() //skip 'if' token
stmt.cond = parser.ParseParenExpression()
if(!parser.CheckToken(")", /token/symbol))
return KW_FAIL
if(!parser.CheckToken("{", /token/symbol, skip=0)) //Token needs to be preserved for parse loop, so skip=0
return KW_ERR
parser.curBlock.statements+=stmt
stmt.block=new
ifstmt.else_if = stmt
parser.AddBlock(stmt.block)
kwElse
Parse(n_Parser/nS_Parser/parser)
.=KW_PASS

View File

@@ -174,8 +174,9 @@
var/loops = 0
for()
loops++
if(loops>=6000)
CRASH("Something TERRIBLE has gone wrong in ParseFunctionStatement ;__;")
if(loops>=800)
errors +=new/scriptError("Cannot find ending params.")
return
if(!curToken)
errors+=new/scriptError/EndOfFile()
@@ -184,6 +185,6 @@
curBlock.statements+=stmt
NextToken() //Skip close parenthesis
return
var/node/expression/P=ParseParamExpression()
var/node/expression/P=ParseParamExpression(check_functions = 1)
stmt.parameters+=P
if(istype(curToken, /token/symbol) && curToken.value==",") NextToken()