diff options
author | Zahary Karadjov <zahary@gmail.com> | 2012-04-20 21:35:59 +0300 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2012-04-20 21:35:59 +0300 |
commit | c1d16c5a4da3f1af6b2e9ce82df29c5397e544ca (patch) | |
tree | ad690a8c716017b89755454d1525be88acc6ea97 /compiler | |
parent | 8319e2411d07503f8ca1475f1ef9009384560c1c (diff) | |
download | Nim-c1d16c5a4da3f1af6b2e9ce82df29c5397e544ca.tar.gz |
made built-in types primary expressions to allow infix operators to be used with them
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/parser.nim | 97 | ||||
-rwxr-xr-x | compiler/semtypes.nim | 6 | ||||
-rwxr-xr-x | compiler/semtypinst.nim | 3 |
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) |