summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/parser.nim38
-rwxr-xr-xdoc/grammar.txt5
-rwxr-xr-xdoc/manual.txt25
-rw-r--r--tests/accept/run/tprecedence.nim11
-rwxr-xr-xtests/tester.nim4
-rwxr-xr-xtodo.txt5
-rwxr-xr-xweb/news.txt2
7 files changed, 64 insertions, 26 deletions
diff --git a/compiler/parser.nim b/compiler/parser.nim
index 13c7a3edb..361c297fb 100755
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -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 = 
diff --git a/doc/grammar.txt b/doc/grammar.txt
index 458c85833..5f7b851fa 100755
--- a/doc/grammar.txt
+++ b/doc/grammar.txt
@@ -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)*
diff --git a/doc/manual.txt b/doc/manual.txt
index 44bd99352..6d8286dd7 100755
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -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

 ================  ===============================================  ==================  ===============

 

 

diff --git a/tests/accept/run/tprecedence.nim b/tests/accept/run/tprecedence.nim
new file mode 100644
index 000000000..6b1b250a2
--- /dev/null
+++ b/tests/accept/run/tprecedence.nim
@@ -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
+
diff --git a/tests/tester.nim b/tests/tester.nim
index 9741d7719..2baffc81d 100755
--- a/tests/tester.nim
+++ b/tests/tester.nim
@@ -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
diff --git a/todo.txt b/todo.txt
index e0fa4d015..608d55b7a 100755
--- a/todo.txt
+++ b/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
diff --git a/web/news.txt b/web/news.txt
index 555b3ef69..d1334ef6f 100755
--- a/web/news.txt
+++ b/web/news.txt
@@ -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