exprs for dynlib; indentation parsing

This commit is contained in:
Andreas Rumpf 2009-12-16 00:38:35 +01:00
commit 10ab814fba
6 changed files with 119 additions and 67 deletions

View file

@ -8,7 +8,7 @@ operator ::= OP0 | OR | XOR | AND | OP3 | OP4 | OP5 | OP6 | OP7
prefixOperator ::= OP0 | OP3 | OP4 | OP5 | OP6 | OP7 | 'not' prefixOperator ::= OP0 | OP3 | OP4 | OP5 | OP6 | OP7 | 'not'
optInd ::= [COMMENT] [IND] optInd ::= [COMMENT] [IND]
optPar ::= [IND] | [SAD]
lowestExpr ::= orExpr (OP0 optInd orExpr)* lowestExpr ::= orExpr (OP0 optInd orExpr)*
orExpr ::= andExpr (OR | 'xor' optInd andExpr)* orExpr ::= andExpr (OR | 'xor' optInd andExpr)*
@ -21,16 +21,16 @@ dollarExpr ::= primary (OP7 optInd primary)*
indexExpr ::= '..' [expr] | expr ['=' expr | '..' expr] indexExpr ::= '..' [expr] | expr ['=' expr | '..' expr]
castExpr ::= 'cast' '[' optInd typeDesc [SAD] ']' '(' optInd expr [SAD] ')' castExpr ::= 'cast' '[' optInd typeDesc optPar ']' '(' optInd expr optPar ')'
addrExpr ::= 'addr' '(' optInd expr ')' addrExpr ::= 'addr' '(' optInd expr optPar ')'
symbol ::= '`' (KEYWORD | IDENT | operator | '(' ')' symbol ::= '`' (KEYWORD | IDENT | operator | '(' ')'
| '[' ']' | '=' | literal)+ '`' | '[' ']' | '=' | literal)+ '`'
| IDENT | IDENT
primaryPrefix ::= (prefixOperator | 'bind') optInd primaryPrefix ::= (prefixOperator | 'bind') optInd
primarySuffix ::= '.' optInd symbol primarySuffix ::= '.' optInd symbol
| '(' optInd namedExprList [SAD] ')' | '(' optInd namedExprList optPar ')'
| '[' optInd [indexExpr (comma indexExpr)* [comma]] [SAD] ']' | '[' optInd [indexExpr (comma indexExpr)* [comma]] optPar ']'
| '^' | '^'
| pragma | pragma
@ -44,9 +44,9 @@ literal ::= INT_LIT | INT8_LIT | INT16_LIT | INT32_LIT | INT64_LIT
| NIL | NIL
constructor ::= literal constructor ::= literal
| '[' optInd colonExprList [SAD] ']' | '[' optInd colonExprList optPar ']'
| '{' optInd sliceExprList [SAD] '}' | '{' optInd sliceExprList optPar '}'
| '(' optInd colonExprList [SAD] ')' | '(' optInd colonExprList optPar ')'
colonExpr ::= expr [':' expr] colonExpr ::= expr [':' expr]
colonExprList ::= [colonExpr (comma colonExpr)* [comma]] colonExprList ::= [colonExpr (comma colonExpr)* [comma]]
@ -128,13 +128,13 @@ importStmt ::= 'import' filename (comma filename)*
includeStmt ::= 'include' filename (comma filename)* includeStmt ::= 'include' filename (comma filename)*
fromStmt ::= 'from' filename 'import' symbol (comma symbol)* fromStmt ::= 'from' filename 'import' symbol (comma symbol)*
pragma ::= '{.' optInd (colonExpr [comma])* [SAD] ('.}' | '}') pragma ::= '{.' optInd (colonExpr [comma])* optPar ('.}' | '}')
param ::= symbol (comma symbol)* (':' typeDesc ['=' expr] | '=' expr) param ::= symbol (comma symbol)* (':' typeDesc ['=' expr] | '=' expr)
paramList ::= ['(' [param (comma param)*] [SAD] ')'] [':' typeDesc] paramList ::= ['(' [param (comma param)*] optPar ')'] [':' typeDesc]
genericParam ::= symbol [':' typeDesc] ['=' expr] genericParam ::= symbol [':' typeDesc] ['=' expr]
genericParams ::= '[' genericParam (comma genericParam)* [SAD] ']' genericParams ::= '[' genericParam (comma genericParam)* optPar ']'
routineDecl := symbol ['*'] [genericParams] paramList [pragma] ['=' stmt] routineDecl := symbol ['*'] [genericParams] paramList [pragma] ['=' stmt]
@ -164,7 +164,7 @@ objectCase ::= 'case' expr ':' typeDesc [COMMENT]
objectPart ::= objectWhen | objectCase | objectIdentPart | 'nil' objectPart ::= objectWhen | objectCase | objectIdentPart | 'nil'
| indPush objectPart (SAD objectPart)* DED indPop | indPush objectPart (SAD objectPart)* DED indPop
tupleDesc ::= '[' optInd [param (comma param)*] [SAD] ']' tupleDesc ::= '[' optInd [param (comma param)*] optPar ']'
objectDef ::= 'object' [pragma] ['of' typeDesc] objectPart objectDef ::= 'object' [pragma] ['of' typeDesc] objectPart
enumField ::= symbol ['=' expr] enumField ::= symbol ['=' expr]

View file

@ -118,17 +118,37 @@ The ``dynlib`` import mechanism supports a versioning scheme:
.. code-block:: nimrod .. code-block:: nimrod
proc Tcl_Eval(interp: pTcl_Interp, script: cstring): int {.cdecl, proc Tcl_Eval(interp: pTcl_Interp, script: cstring): int {.cdecl,
importc, dynlib: "libtcl(8.5|8.4|8.3).so.(1|0)".} importc, dynlib: "libtcl(|8.5|8.4|8.3).so.(1|0)".}
At runtime the dynamic library is searched for (in this order):: At runtime the dynamic library is searched for (in this order)::
libtcl.so.1
libtcl.so.0
libtcl8.5.so.1 libtcl8.5.so.1
libtcl8.4.so.1
libtcl8.3.so.1
libtcl8.5.so.0 libtcl8.5.so.0
libtcl8.4.so.1
libtcl8.4.so.0 libtcl8.4.so.0
libtcl8.3.so.1
libtcl8.3.so.0 libtcl8.3.so.0
The ``dynlib`` pragma supports not only constant strings as argument but also
string expressions in general:
.. code-block:: nimrod
import os
proc getDllName: string =
result = "mylib.dll"
if ExistsFile(result): return
result = "mylib2.dll"
if ExistsFile(result): return
quit("could not load dynamic library")
proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().}
**Note**: Patterns like ``libtcl(|8.5|8.4).so`` are only supported in constant
strings, because they are precompiled.
NoDecl Pragma NoDecl Pragma
~~~~~~~~~~~~~ ~~~~~~~~~~~~~

View file

@ -71,7 +71,7 @@ proc indexExprList(p: var TParser, first: PNode): PNode =
if p.tok.tokType != tkComma: break if p.tok.tokType != tkComma: break
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
optSad(p) optPar(p)
eat(p, tkBracketRi) eat(p, tkBracketRi)
proc exprColonEqExpr(p: var TParser, kind: TNodeKind, tok: TTokType): PNode = proc exprColonEqExpr(p: var TParser, kind: TNodeKind, tok: TTokType): PNode =
@ -133,7 +133,7 @@ proc exprColonEqExprListAux(p: var TParser, elemKind: TNodeKind,
if p.tok.tokType != tkComma: break if p.tok.tokType != tkComma: break
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
optSad(p) optPar(p)
eat(p, endTok) eat(p, endTok)
proc exprColonEqExprList(p: var TParser, kind, elemKind: TNodeKind, proc exprColonEqExprList(p: var TParser, kind, elemKind: TNodeKind,
@ -147,12 +147,12 @@ proc parseCast(p: var TParser): PNode =
eat(p, tkBracketLe) eat(p, tkBracketLe)
optInd(p, result) optInd(p, result)
addSon(result, parseTypeDesc(p)) addSon(result, parseTypeDesc(p))
optSad(p) optPar(p)
eat(p, tkBracketRi) eat(p, tkBracketRi)
eat(p, tkParLe) eat(p, tkParLe)
optInd(p, result) optInd(p, result)
addSon(result, parseExpr(p)) addSon(result, parseExpr(p))
optSad(p) optPar(p)
eat(p, tkParRi) eat(p, tkParRi)
proc parseAddr(p: var TParser): PNode = proc parseAddr(p: var TParser): PNode =
@ -161,7 +161,7 @@ proc parseAddr(p: var TParser): PNode =
eat(p, tkParLe) eat(p, tkParLe)
optInd(p, result) optInd(p, result)
addSon(result, parseExpr(p)) addSon(result, parseExpr(p))
optSad(p) optPar(p)
eat(p, tkParRi) eat(p, tkParRi)
proc identOrLiteral(p: var TParser): PNode = proc identOrLiteral(p: var TParser): PNode =
@ -343,7 +343,7 @@ proc parsePragma(p: var TParser): PNode =
if p.tok.tokType == tkComma: if p.tok.tokType == tkComma:
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
optSad(p) optPar(p)
if (p.tok.tokType == tkCurlyDotRi) or (p.tok.tokType == tkCurlyRi): getTok(p) if (p.tok.tokType == tkCurlyDotRi) or (p.tok.tokType == tkCurlyRi): getTok(p)
else: parMessage(p, errTokenExpected, ".}") else: parMessage(p, errTokenExpected, ".}")
@ -416,7 +416,7 @@ proc parseTuple(p: var TParser): PNode =
if p.tok.tokType != tkComma: break if p.tok.tokType != tkComma: break
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
optSad(p) optPar(p)
eat(p, tkBracketRi) eat(p, tkBracketRi)
proc parseParamList(p: var TParser): PNode = proc parseParamList(p: var TParser): PNode =
@ -437,7 +437,7 @@ proc parseParamList(p: var TParser): PNode =
if p.tok.tokType != tkComma: break if p.tok.tokType != tkComma: break
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
optSad(p) optPar(p)
eat(p, tkParRi) eat(p, tkParRi)
if p.tok.tokType == tkColon: if p.tok.tokType == tkColon:
getTok(p) getTok(p)
@ -801,7 +801,7 @@ proc parseGenericParamList(p: var TParser): PNode =
if p.tok.tokType != tkComma: break if p.tok.tokType != tkComma: break
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
optSad(p) optPar(p)
eat(p, tkBracketRi) eat(p, tkBracketRi)
proc parseRoutine(p: var TParser, kind: TNodeKind): PNode = proc parseRoutine(p: var TParser, kind: TNodeKind): PNode =
@ -1061,7 +1061,7 @@ proc parseVarTuple(p: var TParser): PNode =
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
addSon(result, nil) # no type desc addSon(result, nil) # no type desc
optSad(p) optPar(p)
eat(p, tkParRi) eat(p, tkParRi)
eat(p, tkEquals) eat(p, tkEquals)
optInd(p, result) optInd(p, result)

View file

@ -48,7 +48,7 @@ proc expectIdentOrOpr*(p: TParser)
proc parLineInfo*(p: TParser): TLineInfo proc parLineInfo*(p: TParser): TLineInfo
proc Eat*(p: var TParser, TokType: TTokType) proc Eat*(p: var TParser, TokType: TTokType)
proc skipInd*(p: var TParser) proc skipInd*(p: var TParser)
proc optSad*(p: var TParser) proc optPar*(p: var TParser)
proc optInd*(p: var TParser, n: PNode) proc optInd*(p: var TParser, n: PNode)
proc indAndComment*(p: var TParser, n: PNode) proc indAndComment*(p: var TParser, n: PNode)
proc setBaseFlags*(n: PNode, base: TNumericalBase) proc setBaseFlags*(n: PNode, base: TNumericalBase)
@ -86,8 +86,8 @@ proc skipComment(p: var TParser, node: PNode) =
proc skipInd(p: var TParser) = proc skipInd(p: var TParser) =
if p.tok.tokType == tkInd: getTok(p) if p.tok.tokType == tkInd: getTok(p)
proc optSad(p: var TParser) = proc optPar(p: var TParser) =
if p.tok.tokType == tkSad: getTok(p) if p.tok.tokType == tkSad or p.tok.tokType == tkInd: getTok(p)
proc optInd(p: var TParser, n: PNode) = proc optInd(p: var TParser, n: PNode) =
skipComment(p, n) skipComment(p, n)
@ -166,9 +166,6 @@ proc isOperator(tok: PToken): bool =
result = getPrecedence(tok) >= 0 result = getPrecedence(tok) >= 0
proc parseSymbol(p: var TParser): PNode = proc parseSymbol(p: var TParser): PNode =
var
s: string
id: PIdent
case p.tok.tokType case p.tok.tokType
of tkSymbol: of tkSymbol:
result = newIdentNodeP(p.tok.ident, p) result = newIdentNodeP(p.tok.ident, p)
@ -178,7 +175,7 @@ proc parseSymbol(p: var TParser): PNode =
getTok(p) getTok(p)
case p.tok.tokType case p.tok.tokType
of tkBracketLe: of tkBracketLe:
s = "[" var s = "["
getTok(p) getTok(p)
if (p.tok.tokType == tkOpr) and (p.tok.ident.s == "$"): if (p.tok.tokType == tkOpr) and (p.tok.ident.s == "$"):
s = s & "$.." s = s & "$.."
@ -204,7 +201,7 @@ proc parseSymbol(p: var TParser): PNode =
getTok(p) getTok(p)
eat(p, tkParRi) eat(p, tkParRi)
of tokKeywordLow..tokKeywordHigh, tkSymbol, tkOpr: of tokKeywordLow..tokKeywordHigh, tkSymbol, tkOpr:
id = p.tok.ident var id = p.tok.ident
getTok(p) getTok(p)
if p.tok.tokType == tkEquals: if p.tok.tokType == tkEquals:
addSon(result, newIdentNodeP(getIdent(id.s & '='), p)) addSon(result, newIdentNodeP(getIdent(id.s & '='), p))
@ -283,24 +280,22 @@ proc indexExpr(p: var TParser): PNode =
else: result = a else: result = a
proc indexExprList(p: var TParser, first: PNode): PNode = proc indexExprList(p: var TParser, first: PNode): PNode =
var a: PNode
result = newNodeP(nkBracketExpr, p) result = newNodeP(nkBracketExpr, p)
addSon(result, first) addSon(result, first)
getTok(p) getTok(p)
optInd(p, result) optInd(p, result)
while (p.tok.tokType != tkBracketRi) and (p.tok.tokType != tkEof) and while (p.tok.tokType != tkBracketRi) and (p.tok.tokType != tkEof) and
(p.tok.tokType != tkSad): (p.tok.tokType != tkSad):
a = indexExpr(p) var a = indexExpr(p)
addSon(result, a) addSon(result, a)
if p.tok.tokType != tkComma: break if p.tok.tokType != tkComma: break
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
optSad(p) optPar(p)
eat(p, tkBracketRi) eat(p, tkBracketRi)
proc exprColonEqExpr(p: var TParser, kind: TNodeKind, tok: TTokType): PNode = proc exprColonEqExpr(p: var TParser, kind: TNodeKind, tok: TTokType): PNode =
var a: PNode var a = parseExpr(p)
a = parseExpr(p)
if p.tok.tokType == tok: if p.tok.tokType == tok:
result = newNodeP(kind, p) result = newNodeP(kind, p)
getTok(p) #optInd(p, result); getTok(p) #optInd(p, result);
@ -311,11 +306,10 @@ proc exprColonEqExpr(p: var TParser, kind: TNodeKind, tok: TTokType): PNode =
proc exprListAux(p: var TParser, elemKind: TNodeKind, endTok, sepTok: TTokType, proc exprListAux(p: var TParser, elemKind: TNodeKind, endTok, sepTok: TTokType,
result: PNode) = result: PNode) =
var a: PNode
getTok(p) getTok(p)
optInd(p, result) optInd(p, result)
while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof): while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof):
a = exprColonEqExpr(p, elemKind, sepTok) var a = exprColonEqExpr(p, elemKind, sepTok)
addSon(result, a) addSon(result, a)
if p.tok.tokType != tkComma: break if p.tok.tokType != tkComma: break
getTok(p) getTok(p)
@ -323,22 +317,20 @@ proc exprListAux(p: var TParser, elemKind: TNodeKind, endTok, sepTok: TTokType,
eat(p, endTok) eat(p, endTok)
proc qualifiedIdent(p: var TParser): PNode = proc qualifiedIdent(p: var TParser): PNode =
var a: PNode
result = parseSymbol(p) #optInd(p, result); result = parseSymbol(p) #optInd(p, result);
if p.tok.tokType == tkDot: if p.tok.tokType == tkDot:
getTok(p) getTok(p)
optInd(p, result) optInd(p, result)
a = result var a = result
result = newNodeI(nkDotExpr, a.info) result = newNodeI(nkDotExpr, a.info)
addSon(result, a) addSon(result, a)
addSon(result, parseSymbol(p)) addSon(result, parseSymbol(p))
proc qualifiedIdentListAux(p: var TParser, endTok: TTokType, result: PNode) = proc qualifiedIdentListAux(p: var TParser, endTok: TTokType, result: PNode) =
var a: PNode
getTok(p) getTok(p)
optInd(p, result) optInd(p, result)
while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof): while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof):
a = qualifiedIdent(p) var a = qualifiedIdent(p)
addSon(result, a) #optInd(p, a); addSon(result, a) #optInd(p, a);
if p.tok.tokType != tkComma: break if p.tok.tokType != tkComma: break
getTok(p) getTok(p)
@ -347,17 +339,17 @@ proc qualifiedIdentListAux(p: var TParser, endTok: TTokType, result: PNode) =
proc exprColonEqExprListAux(p: var TParser, elemKind: TNodeKind, proc exprColonEqExprListAux(p: var TParser, elemKind: TNodeKind,
endTok, sepTok: TTokType, result: PNode) = endTok, sepTok: TTokType, result: PNode) =
var a: PNode assert(endTok in {tkCurlyRi, tkCurlyDotRi, tkBracketRi, tkParRi})
getTok(p) getTok(p)
optInd(p, result) optInd(p, result)
while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof) and while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof) and
(p.tok.tokType != tkSad): (p.tok.tokType != tkSad) and (p.tok.tokType != tkInd):
a = exprColonEqExpr(p, elemKind, sepTok) var a = exprColonEqExpr(p, elemKind, sepTok)
addSon(result, a) addSon(result, a)
if p.tok.tokType != tkComma: break if p.tok.tokType != tkComma: break
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
optSad(p) optPar(p)
eat(p, endTok) eat(p, endTok)
proc exprColonEqExprList(p: var TParser, kind, elemKind: TNodeKind, proc exprColonEqExprList(p: var TParser, kind, elemKind: TNodeKind,
@ -371,12 +363,12 @@ proc parseCast(p: var TParser): PNode =
eat(p, tkBracketLe) eat(p, tkBracketLe)
optInd(p, result) optInd(p, result)
addSon(result, parseTypeDesc(p)) addSon(result, parseTypeDesc(p))
optSad(p) optPar(p)
eat(p, tkBracketRi) eat(p, tkBracketRi)
eat(p, tkParLe) eat(p, tkParLe)
optInd(p, result) optInd(p, result)
addSon(result, parseExpr(p)) addSon(result, parseExpr(p))
optSad(p) optPar(p)
eat(p, tkParRi) eat(p, tkParRi)
proc parseAddr(p: var TParser): PNode = proc parseAddr(p: var TParser): PNode =
@ -385,7 +377,7 @@ proc parseAddr(p: var TParser): PNode =
eat(p, tkParLe) eat(p, tkParLe)
optInd(p, result) optInd(p, result)
addSon(result, parseExpr(p)) addSon(result, parseExpr(p))
optSad(p) optPar(p)
eat(p, tkParRi) eat(p, tkParRi)
proc setBaseFlags(n: PNode, base: TNumericalBase) = proc setBaseFlags(n: PNode, base: TNumericalBase) =
@ -577,7 +569,7 @@ proc parsePragma(p: var TParser): PNode =
if p.tok.tokType == tkComma: if p.tok.tokType == tkComma:
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
optSad(p) optPar(p)
if (p.tok.tokType == tkCurlyDotRi) or (p.tok.tokType == tkCurlyRi): getTok(p) if (p.tok.tokType == tkCurlyDotRi) or (p.tok.tokType == tkCurlyRi): getTok(p)
else: parMessage(p, errTokenExpected, ".}") else: parMessage(p, errTokenExpected, ".}")
@ -650,7 +642,7 @@ proc parseTuple(p: var TParser): PNode =
if p.tok.tokType != tkComma: break if p.tok.tokType != tkComma: break
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
optSad(p) optPar(p)
eat(p, tkBracketRi) eat(p, tkBracketRi)
proc parseParamList(p: var TParser): PNode = proc parseParamList(p: var TParser): PNode =
@ -673,7 +665,7 @@ proc parseParamList(p: var TParser): PNode =
if p.tok.tokType != tkComma: break if p.tok.tokType != tkComma: break
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
optSad(p) optPar(p)
eat(p, tkParRi) eat(p, tkParRi)
if p.tok.tokType == tkColon: if p.tok.tokType == tkColon:
getTok(p) getTok(p)
@ -1035,7 +1027,7 @@ proc parseGenericParamList(p: var TParser): PNode =
if p.tok.tokType != tkComma: break if p.tok.tokType != tkComma: break
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
optSad(p) optPar(p)
eat(p, tkBracketRi) eat(p, tkBracketRi)
proc parseRoutine(p: var TParser, kind: TNodeKind): PNode = proc parseRoutine(p: var TParser, kind: TNodeKind): PNode =
@ -1283,7 +1275,7 @@ proc parseVarTuple(p: var TParser): PNode =
getTok(p) getTok(p)
optInd(p, a) optInd(p, a)
addSon(result, nil) # no type desc addSon(result, nil) # no type desc
optSad(p) optPar(p)
eat(p, tkParRi) eat(p, tkParRi)
eat(p, tkEquals) eat(p, tkEquals)
optInd(p, result) optInd(p, result)

16
tests/tdllvar.nim Executable file
View file

@ -0,0 +1,16 @@
import os
proc getDllName: string =
result = "mylib.dll"
if ExistsFile(result): return
result = "mylib2.dll"
if ExistsFile(result): return
quit("could not load dynamic library")
proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().}
proc myImport2(s: int) {.cdecl, importc, dynlib: getDllName().}
myImport("test2")
myImport2(12)

24
tests/tindent1.nim Executable file
View file

@ -0,0 +1,24 @@
const romanNumbers1 =
[
("M", 1000), ("D", 500), ("C", 100),
("L", 50), ("X", 10), ("V", 5), ("I", 1) ]
const romanNumbers2 =
[
("M", 1000), ("D", 500), ("C", 100),
("L", 50), ("X", 10), ("V", 5), ("I", 1)
]
const romanNumbers3 =
[
("M", 1000), ("D", 500), ("C", 100),
("L", 50), ("X", 10), ("V", 5), ("I", 1)
]
const romanNumbers4 = [
("M", 1000), ("D", 500), ("C", 100),
("L", 50), ("X", 10), ("V", 5), ("I", 1)
]