made built-in types primary expressions to allow infix operators to be used with them
This commit is contained in:
parent
8319e2411d
commit
c1d16c5a4d
3 changed files with 52 additions and 54 deletions
|
|
@ -477,42 +477,8 @@ proc primarySuffix(p: var TParser, r: PNode): PNode =
|
||||||
result = indexExprList(p, result, nkCurlyExpr, tkCurlyRi)
|
result = indexExprList(p, result, nkCurlyExpr, tkCurlyRi)
|
||||||
else: break
|
else: break
|
||||||
|
|
||||||
proc primary(p: var TParser, skipSuffix = false): PNode =
|
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 lowestExprAux(p: var TParser, limit: int): PNode =
|
proc lowestExprAux(p: var TParser, limit: int): PNode =
|
||||||
result = primary(p)
|
result = primary(p)
|
||||||
# expand while operators have priorities higher than 'limit'
|
# expand while operators have priorities higher than 'limit'
|
||||||
|
|
@ -724,39 +690,70 @@ proc parseTypeDescKAux(p: var TParser, kind: TNodeKind): PNode =
|
||||||
result = newNodeP(kind, p)
|
result = newNodeP(kind, p)
|
||||||
getTok(p)
|
getTok(p)
|
||||||
optInd(p, result)
|
optInd(p, result)
|
||||||
if isExprStart(p):
|
if not isOperator(p.tok) and isExprStart(p):
|
||||||
addSon(result, parseTypeDesc(p))
|
addSon(result, parseTypeDesc(p))
|
||||||
|
|
||||||
proc parseExpr(p: var TParser): PNode =
|
proc parseExpr(p: var TParser): PNode =
|
||||||
#
|
#
|
||||||
#expr ::= lowestExpr
|
#expr ::= lowestExpr
|
||||||
# | 'if' expr ':' expr ('elif' expr ':' expr)* 'else' ':' expr
|
# | 'if' expr ':' expr ('elif' expr ':' expr)* 'else' ':' expr
|
||||||
# | 'var' [expr]
|
# | 'when' expr ':' expr ('elif' expr ':' expr)* 'else' ':' expr
|
||||||
# | 'ref' [expr]
|
|
||||||
# | 'ptr' [expr]
|
|
||||||
# | 'type' expr
|
|
||||||
# | 'tuple' [tupleDesc]
|
|
||||||
# | 'enum'
|
|
||||||
# | 'object'
|
|
||||||
# |
|
|
||||||
# | 'proc' paramList [pragma] ['=' stmt]
|
|
||||||
#
|
#
|
||||||
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 tkVar: result = parseTypeDescKAux(p, nkVarTy)
|
||||||
of tkRef: result = parseTypeDescKAux(p, nkRefTy)
|
of tkRef: result = parseTypeDescKAux(p, nkRefTy)
|
||||||
of tkPtr: result = parseTypeDescKAux(p, nkPtrTy)
|
of tkPtr: result = parseTypeDescKAux(p, nkPtrTy)
|
||||||
of tkType: result = parseTypeDescKAux(p, nkTypeOfExpr)
|
of tkType: result = parseTypeDescKAux(p, nkTypeOfExpr)
|
||||||
of tkTuple: result = parseTuple(p)
|
of tkTuple: result = parseTuple(p)
|
||||||
of tkProc: result = parseProcExpr(p, true)
|
of tkProc: result = parseProcExpr(p, true)
|
||||||
of tkIf: result = parseIfExpr(p, nkIfExpr)
|
|
||||||
of tkWhen: result = parseIfExpr(p, nkWhenExpr)
|
|
||||||
of tkEnum:
|
of tkEnum:
|
||||||
result = newNodeP(nkEnumTy, p)
|
result = newNodeP(nkEnumTy, p)
|
||||||
getTok(p)
|
getTok(p)
|
||||||
of tkObject:
|
of tkObject:
|
||||||
result = newNodeP(nkObjectTy, p)
|
result = newNodeP(nkObjectTy, p)
|
||||||
getTok(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 =
|
proc parseTypeDesc(p: var TParser): PNode =
|
||||||
if p.tok.toktype == tkProc: result = parseProcExpr(p, false)
|
if p.tok.toktype == tkProc: result = parseProcExpr(p, false)
|
||||||
|
|
|
||||||
|
|
@ -708,8 +708,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
|
if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
|
||||||
else: GlobalError(n.info, errTypeExpected)
|
else: GlobalError(n.info, errTypeExpected)
|
||||||
of nkCallKinds:
|
of nkCallKinds:
|
||||||
let op = n.sons[0].ident.id
|
let op = n.sons[0].ident
|
||||||
if op in {ord(wAnd), ord(wOr)}:
|
if op.id in {ord(wAnd), ord(wOr)} or op.s == "|":
|
||||||
var
|
var
|
||||||
t1 = semTypeNode(c, n.sons[1], nil)
|
t1 = semTypeNode(c, n.sons[1], nil)
|
||||||
t2 = semTypeNode(c, n.sons[2], 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 = newTypeS(tyTypeClass, c)
|
||||||
result.addSon(t1)
|
result.addSon(t1)
|
||||||
result.addSon(t2)
|
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:
|
else:
|
||||||
result = semTypeFromMacro(c, n)
|
result = semTypeFromMacro(c, n)
|
||||||
of nkCurlyExpr:
|
of nkCurlyExpr:
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ proc checkPartialConstructedType(info: TLineInfo, t: PType) =
|
||||||
LocalError(info, errVarVarTypeNotAllowed)
|
LocalError(info, errVarVarTypeNotAllowed)
|
||||||
|
|
||||||
proc checkConstructedType*(info: TLineInfo, t: PType) =
|
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")
|
LocalError(info, errInvalidPragmaX, "acyclic")
|
||||||
elif t.kind == tyVar and t.sons[0].kind == tyVar:
|
elif t.kind == tyVar and t.sons[0].kind == tyVar:
|
||||||
LocalError(info, errVarVarTypeNotAllowed)
|
LocalError(info, errVarVarTypeNotAllowed)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue