mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-25 04:15:09 +00:00
operator precedence changed: assignment like operators are supported; escaping of operators with \ is supported
This commit is contained in:
@@ -153,20 +153,30 @@ proc IsLeftAssociative(tok: TToken): bool {.inline.} =
|
||||
|
||||
proc getPrecedence(tok: TToken): int =
|
||||
case tok.tokType
|
||||
of tkOpr:
|
||||
case tok.ident.s[0]
|
||||
of '$', '^': result = 9
|
||||
of '*', '%', '/', '\\': result = 8
|
||||
of '+', '-', '~', '|': result = 7
|
||||
of '&': result = 6
|
||||
of '=', '<', '>', '!': result = 4
|
||||
of '.': result = 5
|
||||
else: result = 1
|
||||
of tkDiv, tkMod, tkShl, tkShr: result = 8
|
||||
of tkIn, tkNotIn, tkIs, tkIsNot, tkNot, tkOf: result = 4
|
||||
of tkDotDot: result = 5
|
||||
of tkAnd: result = 3
|
||||
of tkOr, tkXor: result = 2
|
||||
of tkOpr:
|
||||
var relevantChar = tok.ident.s[0]
|
||||
var L = tok.ident.s.len
|
||||
if relevantChar == '\\' and L > 1:
|
||||
relevantChar = tok.ident.s[1]
|
||||
|
||||
template considerAsgn(value: expr) =
|
||||
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: result = 5
|
||||
of tkDotDot: result = 6
|
||||
of tkAnd: result = 4
|
||||
of tkOr, tkXor: result = 3
|
||||
else: result = - 10
|
||||
|
||||
proc isOperator(tok: TToken): bool =
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module ::= ([COMMENT] [SAD] stmt)*
|
||||
|
||||
comma ::= ',' [COMMENT] [IND]
|
||||
operator ::= OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9
|
||||
operator ::= OP0 | OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9
|
||||
| 'or' | 'xor' | 'and'
|
||||
| 'is' | 'isnot' | 'in' | 'notin' | 'of'
|
||||
| 'div' | 'mod' | 'shl' | 'shr' | 'not' | '..'
|
||||
@@ -11,7 +11,8 @@ prefixOperator ::= operator
|
||||
optInd ::= [COMMENT] [IND]
|
||||
optPar ::= [IND] | [SAD]
|
||||
|
||||
lowestExpr ::= orExpr (OP1 optInd orExpr)*
|
||||
lowestExpr ::= assignExpr (OP0 optInd assignExpr)*
|
||||
assignExpr ::= orExpr (OP1 optInd orExpr)*
|
||||
orExpr ::= andExpr (OP2 optInd andExpr)*
|
||||
andExpr ::= cmpExpr (OP3 optInd cmpExpr)*
|
||||
cmpExpr ::= sliceExpr (OP4 optInd sliceExpr)*
|
||||
|
||||
@@ -387,13 +387,25 @@ This section lists Nimrod's standard syntax in ENBF. How the parser receives
|
||||
indentation tokens is already described in the `Lexical Analysis`_ section.
|
||||
|
||||
Nimrod allows user-definable operators.
|
||||
Binary operators have 9 different levels of precedence. For user-defined
|
||||
operators, the precedence depends on the first character the operator consists
|
||||
of. All binary operators are left-associative, except binary operators starting
|
||||
with (or only consisting of) ``^``.
|
||||
Binary operators have 10 different levels of precedence.
|
||||
All binary operators are left-associative, except binary operators starting
|
||||
with (or only consisting of) ``^``.
|
||||
|
||||
For operators that are not keywords the precedence is determined by the
|
||||
following rules:
|
||||
|
||||
An operator symbol's *relevant character* is its first
|
||||
character unless the first character is ``\`` and its length is greater than 1
|
||||
then it is the second character.
|
||||
|
||||
If the operator ends with ``=`` and its relevant character is none of
|
||||
``<``, ``>``, ``!``, ``=``, ``~``, ``?``, it is an *assignment operator* which
|
||||
has the lowest precedence.
|
||||
|
||||
Otherwise precedence is determined by the relevant character.
|
||||
|
||||
================ =============================================== ================== ===============
|
||||
Precedence level Operators First characters Terminal symbol
|
||||
Precedence level Operators Relevant character Terminal symbol
|
||||
================ =============================================== ================== ===============
|
||||
9 (highest) ``$ ^`` OP9
|
||||
8 ``* / div mod shl shr %`` ``* % \ /`` OP8
|
||||
@@ -403,7 +415,8 @@ Precedence level Operators First charact
|
||||
4 ``== <= < >= > != in not_in is isnot not of`` ``= < > !`` OP4
|
||||
3 ``and`` OP3
|
||||
2 ``or xor`` OP2
|
||||
1 (lowest) ``@ : ?`` OP1
|
||||
1 ``@ : ?`` OP1
|
||||
0 (lowest) *assignment operator* (like ``+=``, ``*=``) OP0
|
||||
================ =============================================== ================== ===============
|
||||
|
||||
|
||||
|
||||
11
tests/accept/run/tprecedence.nim
Normal file
11
tests/accept/run/tprecedence.nim
Normal file
@@ -0,0 +1,11 @@
|
||||
discard """
|
||||
output: "true"
|
||||
"""
|
||||
|
||||
# Test the new predence rules
|
||||
|
||||
proc `\+` (x, y: int): int = result = x + y
|
||||
proc `\*` (x, y: int): int = result = x * y
|
||||
|
||||
echo 5 \+ 1 \* 9 == 14
|
||||
|
||||
@@ -417,6 +417,10 @@ proc main() =
|
||||
var runRes = readResults(runJson)
|
||||
listResults(rejectRes, compileRes, runRes)
|
||||
outputJSON(rejectRes, compileRes, runRes)
|
||||
of "dll":
|
||||
var r = initResults()
|
||||
runDLLTests r, p.cmdLineRest.string
|
||||
echo r.data, r
|
||||
of "test":
|
||||
var r = initResults()
|
||||
if p.kind != cmdArgument: quit usage
|
||||
|
||||
5
todo.txt
5
todo.txt
@@ -4,14 +4,11 @@ Version 0.8.14
|
||||
- bug: s[1..n] = @[] produces wrong C code
|
||||
- optimize unused constants away (affected by HLO)
|
||||
- fix actors.nim; test with different thread var implementations
|
||||
- dead code elim for JS backend
|
||||
|
||||
version 0.9.0
|
||||
=============
|
||||
|
||||
- special precedence rules for assignment operators: If the operator ends with
|
||||
'=' and does **not** start with '<', '>', '!', '=', '~', '?', it is an
|
||||
assignment operator
|
||||
- dead code elim for JS backend; 'of' operator for JS backend
|
||||
- test the sort implementation again
|
||||
- 'let x = y'
|
||||
- const ptr/ref
|
||||
|
||||
@@ -44,6 +44,8 @@ Changes affecting backwards compatibility
|
||||
raise hooks.
|
||||
- Changed exception handling/error reporting for ``os.removeFile`` and
|
||||
``os.removeDir``.
|
||||
- Operators now have diffent precedence rules: Assignment-like operators
|
||||
(like ``*=``) are now special-cased.
|
||||
|
||||
|
||||
Language Additions
|
||||
|
||||
Reference in New Issue
Block a user