next steps for the new parser

This commit is contained in:
Araq 2013-04-20 03:03:12 +02:00
commit 7e329db45f
2 changed files with 33 additions and 32 deletions

View file

@ -711,7 +711,7 @@ var
proc writeSurroundingSrc(info: TLineInfo) = proc writeSurroundingSrc(info: TLineInfo) =
const indent = " " const indent = " "
MsgWriteln(indent & info.sourceLine.data) MsgWriteln(indent & info.sourceLine.ropeToStr)
MsgWriteln(indent & repeatChar(info.col, ' ') & '^') MsgWriteln(indent & repeatChar(info.col, ' ') & '^')
proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string, proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string,

View file

@ -25,7 +25,7 @@ when isMainModule:
outp.close outp.close
import import
llstream, lexer, idents, strutils, ast, msgs llstream, lexer, idents, strutils, ast, astalgo, msgs
type type
TParser*{.final.} = object # a TParser object represents a module that TParser*{.final.} = object # a TParser object represents a module that
@ -933,21 +933,24 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode =
if mode != pmSkipSuffix: if mode != pmSkipSuffix:
result = primarySuffix(p, result) result = primarySuffix(p, result)
proc parseTypeDesc(p: var TParser): PNode = proc parseTypeDesc(p: var TParser): PNode =
#| typeDesc = lowestExpr
result = lowestExpr(p, pmTypeDesc) result = lowestExpr(p, pmTypeDesc)
proc parseTypeDefAux(p: var TParser): PNode = proc parseTypeDefAux(p: var TParser): PNode =
#| typeDefAux = lowestExpr
result = lowestExpr(p, pmTypeDef) result = lowestExpr(p, pmTypeDef)
proc parseExprStmt(p: var TParser): PNode = proc parseExprStmt(p: var TParser): PNode =
#| exprStmt = lowestExpr ( #| exprStmt = lowestExpr
#| '=' optInd expr #| (( '=' optInd expr )
#| / doBlocks #| / ( expr ^+ comma
#| / ':' stmt? ( IND{=} 'of' exprList ':' stmt #| doBlocks
#| | IND{=} 'elif' expr ':' stmt #| / ':' stmt? ( IND{=} 'of' exprList ':' stmt
#| | IND{=} 'except' exprList ':' stmt #| | IND{=} 'elif' expr ':' stmt
#| | IND{=} 'else' ':' stmt )* #| | IND{=} 'except' exprList ':' stmt
#| ) #| | IND{=} 'else' ':' stmt )*
#| ))?
var a = lowestExpr(p) var a = lowestExpr(p)
if p.tok.tokType == tkEquals: if p.tok.tokType == tkEquals:
getTok(p) getTok(p)
@ -957,23 +960,20 @@ proc parseExprStmt(p: var TParser): PNode =
addSon(result, a) addSon(result, a)
addSon(result, b) addSon(result, b)
else: else:
var call = if a.kind == nkCall: a if p.tok.indent < 0 and isExprStart(p):
else: newNode(nkCommand, a.info, @[a]) result = newNode(nkCommand, a.info, @[a])
# XXX this is clearly a bug: p(a, b) c should not parse as p(a, b, c)! while true:
while true: var e = parseExpr(p)
if not isExprStart(p): break addSon(result, e)
var e = parseExpr(p) if p.tok.tokType != tkComma: break
addSon(call, e) getTok(p)
if p.tok.tokType != tkComma: break optInd(p, result)
getTok(p) else:
optInd(p, a) result = a
if p.tok.tokType == tkDo: if p.tok.tokType == tkDo and p.tok.indent < 0:
parseDoBlocks(p, call) parseDoBlocks(p, result)
return return result
result = if call.sonsLen <= 1: a
else: call
if p.tok.tokType == tkColon: if p.tok.tokType == tkColon:
result = call
getTok(p) getTok(p)
skipComment(p, result) skipComment(p, result)
if p.tok.TokType notin {tkOf, tkElif, tkElse, tkExcept}: if p.tok.TokType notin {tkOf, tkElif, tkElse, tkExcept}:
@ -1326,6 +1326,7 @@ proc newCommentStmt(p: var TParser): PNode =
#| commentStmt = COMMENT #| commentStmt = COMMENT
result = newNodeP(nkCommentStmt, p) result = newNodeP(nkCommentStmt, p)
result.info.line = result.info.line - int16(1) - int16(p.tok.iNumber) result.info.line = result.info.line - int16(1) - int16(p.tok.iNumber)
getTok(p)
type type
TDefParser = proc (p: var TParser): PNode {.nimcall.} TDefParser = proc (p: var TParser): PNode {.nimcall.}
@ -1347,7 +1348,6 @@ proc parseSection(p: var TParser, kind: TNodeKind,
addSon(result, a) addSon(result, a)
of tkComment: of tkComment:
var a = newCommentStmt(p) var a = newCommentStmt(p)
skipComment(p, a)
addSon(result, a) addSon(result, a)
else: else:
parMessage(p, errIdentifierExpected, p.tok) parMessage(p, errIdentifierExpected, p.tok)
@ -1395,7 +1395,8 @@ proc parseEnum(p: var TParser): PNode =
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
addSon(result, a) addSon(result, a)
if p.tok.indent > 0 and p.tok.indent <= p.currInd or p.tok.tokType == tkEof: if p.tok.indent >= 0 and p.tok.indent <= p.currInd or
p.tok.tokType == tkEof:
break break
if result.len <= 1: if result.len <= 1:
lexMessage(p.lex, errIdentifierExpected, prettyTok(p.tok)) lexMessage(p.lex, errIdentifierExpected, prettyTok(p.tok))
@ -1610,7 +1611,7 @@ proc simpleStmt(p: var TParser): PNode =
else: else:
if isExprStart(p): result = parseExprStmt(p) if isExprStart(p): result = parseExprStmt(p)
else: result = ast.emptyNode else: result = ast.emptyNode
if result.kind != nkEmpty: skipComment(p, result) if result.kind notin {nkEmpty, nkCommentStmt}: skipComment(p, result)
proc complexOrSimpleStmt(p: var TParser): PNode = proc complexOrSimpleStmt(p: var TParser): PNode =
#| complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt #| complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt
@ -1685,8 +1686,6 @@ proc parseStmt(p: var TParser): PNode =
proc parseAll(p: var TParser): PNode = proc parseAll(p: var TParser): PNode =
result = newNodeP(nkStmtList, p) result = newNodeP(nkStmtList, p)
while p.tok.tokType != tkEof: while p.tok.tokType != tkEof:
if p.tok.indent != p.currInd:
parMessage(p, errInvalidIndentation)
var a = complexOrSimpleStmt(p) var a = complexOrSimpleStmt(p)
if a.kind != nkEmpty: if a.kind != nkEmpty:
addSon(result, a) addSon(result, a)
@ -1694,6 +1693,8 @@ proc parseAll(p: var TParser): PNode =
parMessage(p, errExprExpected, p.tok) parMessage(p, errExprExpected, p.tok)
# bugfix: consume a token here to prevent an endless loop: # bugfix: consume a token here to prevent an endless loop:
getTok(p) getTok(p)
if p.tok.indent != 0:
parMessage(p, errInvalidIndentation)
proc parseTopLevelStmt(p: var TParser): PNode = proc parseTopLevelStmt(p: var TParser): PNode =
result = ast.emptyNode result = ast.emptyNode