summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2012-04-20 21:35:59 +0300
committerZahary Karadjov <zahary@gmail.com>2012-04-20 21:35:59 +0300
commitc1d16c5a4da3f1af6b2e9ce82df29c5397e544ca (patch)
treead690a8c716017b89755454d1525be88acc6ea97 /compiler
parent8319e2411d07503f8ca1475f1ef9009384560c1c (diff)
downloadNim-c1d16c5a4da3f1af6b2e9ce82df29c5397e544ca.tar.gz
made built-in types primary expressions to allow infix operators to be used with them
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/parser.nim97
-rwxr-xr-xcompiler/semtypes.nim6
-rwxr-xr-xcompiler/semtypinst.nim3
3 files changed, 52 insertions, 54 deletions
diff --git a/compiler/parser.nim b/compiler/parser.nim
index 78e5b2455..e90860578 100755
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -477,42 +477,8 @@ proc primarySuffix(p: var TParser, r: PNode): PNode =
       result = indexExprList(p, result, nkCurlyExpr, tkCurlyRi)
     else: break
 
-proc primary(p: var TParser, skipSuffix = false): PNode = 
-  # prefix operator?
-  if isOperator(p.tok):
-    let isSigil = IsSigilLike(p.tok)
-    result = newNodeP(nkPrefix, p)
-    var a = newIdentNodeP(p.tok.ident, p)
-    addSon(result, a)
-    getTok(p)
-    optInd(p, a)
-    if isSigil: 
-      #XXX prefix operators
-      addSon(result, primary(p, true))
-      result = primarySuffix(p, result)
-    else:
-      addSon(result, primary(p))
-    return
-  elif p.tok.tokType == tkAddr:
-    result = newNodeP(nkAddr, p)
-    getTok(p)
-    addSon(result, primary(p))
-    return
-  elif p.tok.tokType == tkStatic:
-    result = newNodeP(nkStaticExpr, p)
-    getTok(p)
-    addSon(result, primary(p))
-    return
-  elif p.tok.tokType == tkBind: 
-    result = newNodeP(nkBind, p)
-    getTok(p)
-    optInd(p, result)
-    addSon(result, primary(p))
-    return 
-  result = identOrLiteral(p)
-  if not skipSuffix:
-    result = primarySuffix(p, result)
-  
+proc primary(p: var TParser, skipSuffix = false): PNode
+
 proc lowestExprAux(p: var TParser, limit: int): PNode = 
   result = primary(p) 
   # expand while operators have priorities higher than 'limit'
@@ -724,39 +690,70 @@ proc parseTypeDescKAux(p: var TParser, kind: TNodeKind): PNode =
   result = newNodeP(kind, p)
   getTok(p)
   optInd(p, result)
-  if isExprStart(p):
+  if not isOperator(p.tok) and isExprStart(p):
     addSon(result, parseTypeDesc(p))
 
 proc parseExpr(p: var TParser): PNode = 
   #
   #expr ::= lowestExpr
   #     | 'if' expr ':' expr ('elif' expr ':' expr)* 'else' ':' expr
-  #     | 'var' [expr]
-  #     | 'ref' [expr]
-  #     | 'ptr' [expr]
-  #     | 'type' expr
-  #     | 'tuple' [tupleDesc]
-  #     | 'enum'
-  #     | 'object'
-  #     | 
-  #     | 'proc' paramList [pragma] ['=' stmt] 
+  #     | 'when' expr ':' expr ('elif' expr ':' expr)* 'else' ':' expr
   #
-  case p.tok.toktype
+  case p.tok.tokType:
+  of tkIf: result = parseIfExpr(p, nkIfExpr)
+  of tkWhen: result = parseIfExpr(p, nkWhenExpr)
+  else: result = lowestExpr(p)
+
+proc primary(p: var TParser, skipSuffix = false): PNode = 
+  # prefix operator?
+  if isOperator(p.tok):
+    let isSigil = IsSigilLike(p.tok)
+    result = newNodeP(nkPrefix, p)
+    var a = newIdentNodeP(p.tok.ident, p)
+    addSon(result, a)
+    getTok(p)
+    optInd(p, a)
+    if isSigil: 
+      #XXX prefix operators
+      addSon(result, primary(p, true))
+      result = primarySuffix(p, result)
+    else:
+      addSon(result, primary(p))
+    return
+  
+  case p.tok.tokType:
   of tkVar: result = parseTypeDescKAux(p, nkVarTy)
   of tkRef: result = parseTypeDescKAux(p, nkRefTy)
   of tkPtr: result = parseTypeDescKAux(p, nkPtrTy)
   of tkType: result = parseTypeDescKAux(p, nkTypeOfExpr)
   of tkTuple: result = parseTuple(p)
   of tkProc: result = parseProcExpr(p, true)
-  of tkIf: result = parseIfExpr(p, nkIfExpr)
-  of tkWhen: result = parseIfExpr(p, nkWhenExpr)
   of tkEnum:
     result = newNodeP(nkEnumTy, p)
     getTok(p)
   of tkObject:
     result = newNodeP(nkObjectTy, p)
     getTok(p)
-  else: result = lowestExpr(p)
+  of tkDistinct:
+    result = newNodeP(nkDistinctTy, p)
+    getTok(p)
+  of tkAddr:
+    result = newNodeP(nkAddr, p)
+    getTok(p)
+    addSon(result, primary(p))
+  of tkStatic:
+    result = newNodeP(nkStaticExpr, p)
+    getTok(p)
+    addSon(result, primary(p))
+  of tkBind: 
+    result = newNodeP(nkBind, p)
+    getTok(p)
+    optInd(p, result)
+    addSon(result, primary(p))
+  else:
+    result = identOrLiteral(p)
+    if not skipSuffix:
+      result = primarySuffix(p, result)
   
 proc parseTypeDesc(p: var TParser): PNode = 
   if p.tok.toktype == tkProc: result = parseProcExpr(p, false)
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index b9bab5da6..28ef55274 100755
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -708,8 +708,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
     if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
     else: GlobalError(n.info, errTypeExpected)
   of nkCallKinds:
-    let op = n.sons[0].ident.id
-    if op in {ord(wAnd), ord(wOr)}:
+    let op = n.sons[0].ident
+    if op.id in {ord(wAnd), ord(wOr)} or op.s == "|":
       var
         t1 = semTypeNode(c, n.sons[1], nil)
         t2 = semTypeNode(c, n.sons[2], nil)
@@ -720,7 +720,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
         result = newTypeS(tyTypeClass, c)
         result.addSon(t1)
         result.addSon(t2)
-        result.flags.incl(if op == ord(wAnd): tfAll else: tfAny)
+        result.flags.incl(if op.id == ord(wAnd): tfAll else: tfAny)
     else:
       result = semTypeFromMacro(c, n)
   of nkCurlyExpr:
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index 0c44205de..4a576c00d 100755
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -18,7 +18,8 @@ proc checkPartialConstructedType(info: TLineInfo, t: PType) =
     LocalError(info, errVarVarTypeNotAllowed)
 
 proc checkConstructedType*(info: TLineInfo, t: PType) = 
-  if tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject: 
+  if t.kind in {tyTypeClass}: nil
+  elif tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject: 
     LocalError(info, errInvalidPragmaX, "acyclic")
   elif t.kind == tyVar and t.sons[0].kind == tyVar: 
     LocalError(info, errVarVarTypeNotAllowed)