diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-09-11 16:41:34 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-09-11 16:41:34 +0200 |
commit | af94946517d4e07e91b5c5ca21d58645f6da86c4 (patch) | |
tree | a393b463691766cac615049e772fab9966477270 /compiler/lexer.nim | |
parent | 49708d9c2564762904e2405135926afe55a48009 (diff) | |
parent | 9ba80d204407cafeaf195dbe7b144b16b84dca6e (diff) | |
download | Nim-af94946517d4e07e91b5c5ca21d58645f6da86c4.tar.gz |
Merge branch 'devel' of github.com:nim-lang/Nim into devel
Diffstat (limited to 'compiler/lexer.nim')
-rw-r--r-- | compiler/lexer.nim | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/compiler/lexer.nim b/compiler/lexer.nim index 6ad1d9fc6..278fa1e54 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -884,6 +884,42 @@ proc getOperator(L: var TLexer, tok: var TToken) = if buf[pos] in {CR, LF, nimlexbase.EndOfFile}: tok.strongSpaceB = -1 +proc getPrecedence*(tok: TToken, strongSpaces: bool): int = + ## Calculates the precedence of the given token. + template considerStrongSpaces(x): untyped = + x + (if strongSpaces: 100 - tok.strongSpaceA.int*10 else: 0) + + case tok.tokType + of tkOpr: + let L = tok.ident.s.len + let relevantChar = tok.ident.s[0] + + # arrow like? + if L > 1 and tok.ident.s[L-1] == '>' and + tok.ident.s[L-2] in {'-', '~', '='}: return considerStrongSpaces(1) + + template considerAsgn(value: untyped) = + result = if tok.ident.s[L-1] == '=': 1 else: value + + case relevantChar + of '$', '^': considerAsgn(10) + of '*', '%', '/', '\\': considerAsgn(9) + of '~': result = 8 + of '+', '-', '|': considerAsgn(8) + of '&': considerAsgn(7) + of '=', '<', '>', '!': result = 5 + of '.': considerAsgn(6) + of '?': result = 2 + else: considerAsgn(2) + of tkDiv, tkMod, tkShl, tkShr: result = 9 + of tkIn, tkNotin, tkIs, tkIsnot, tkNot, tkOf, tkAs: result = 5 + of tkDotDot: result = 6 + of tkAnd: result = 4 + of tkOr, tkXor, tkPtr, tkRef: result = 3 + else: return -10 + result = considerStrongSpaces(result) + + proc newlineFollows*(L: TLexer): bool = var pos = L.bufpos var buf = L.buf @@ -1249,3 +1285,14 @@ proc getIndentWidth*(fileIdx: FileIndex, inputstream: PLLStream; result = tok.indent if result > 0 or tok.tokType == tkEof: break closeLexer(lex) + +proc getPrecedence*(ident: PIdent): int = + ## assumes ident is binary operator already + var tok: TToken + initToken(tok) + tok.ident = ident + tok.tokType = + if tok.ident.id in ord(tokKeywordLow) - ord(tkSymbol) .. ord(tokKeywordHigh) - ord(tkSymbol): + TTokType(tok.ident.id + ord(tkSymbol)) + else: tkOpr + getPrecedence(tok, false) |