c2nim: added some scope operator parsing
This commit is contained in:
parent
596496f695
commit
0a851c869f
3 changed files with 44 additions and 18 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# c2nim - C to Nimrod source converter
|
# c2nim - C to Nimrod source converter
|
||||||
# (c) Copyright 2012 Andreas Rumpf
|
# (c) Copyright 2013 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -12,9 +12,9 @@
|
||||||
## used to convert the AST to its text representation.
|
## used to convert the AST to its text representation.
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
# - implement handling of '::'
|
# - document 'cpp' mode
|
||||||
|
# - implement handling of '::': function declarations
|
||||||
# - C++'s "operator" still needs some love
|
# - C++'s "operator" still needs some love
|
||||||
# - ignore 'using' statements
|
|
||||||
# - support '#if' in classes
|
# - support '#if' in classes
|
||||||
|
|
||||||
import
|
import
|
||||||
|
|
@ -46,6 +46,7 @@ type
|
||||||
dynlibSym, header: string
|
dynlibSym, header: string
|
||||||
macros: seq[TMacro]
|
macros: seq[TMacro]
|
||||||
toMangle: PStringTable
|
toMangle: PStringTable
|
||||||
|
classes: PStringTable
|
||||||
PParserOptions* = ref TParserOptions
|
PParserOptions* = ref TParserOptions
|
||||||
|
|
||||||
TParser* = object
|
TParser* = object
|
||||||
|
|
@ -71,6 +72,7 @@ proc newParserOptions*(): PParserOptions =
|
||||||
result.dynlibSym = ""
|
result.dynlibSym = ""
|
||||||
result.header = ""
|
result.header = ""
|
||||||
result.toMangle = newStringTable(modeCaseSensitive)
|
result.toMangle = newStringTable(modeCaseSensitive)
|
||||||
|
result.classes = newStringTable(modeCaseSensitive)
|
||||||
|
|
||||||
proc setOption*(parserOptions: PParserOptions, key: string, val=""): bool =
|
proc setOption*(parserOptions: PParserOptions, key: string, val=""): bool =
|
||||||
result = true
|
result = true
|
||||||
|
|
@ -88,6 +90,7 @@ proc setOption*(parserOptions: PParserOptions, key: string, val=""): bool =
|
||||||
of "cpp": incl(parserOptions.flags, pfCpp)
|
of "cpp": incl(parserOptions.flags, pfCpp)
|
||||||
of "keepbodies": incl(parserOptions.flags, pfKeepBodies)
|
of "keepbodies": incl(parserOptions.flags, pfKeepBodies)
|
||||||
of "ignorervaluerefs": incl(parserOptions.flags, pfIgnoreRValueRefs)
|
of "ignorervaluerefs": incl(parserOptions.flags, pfIgnoreRValueRefs)
|
||||||
|
of "class": parserOptions.classes[val] = "true"
|
||||||
else: result = false
|
else: result = false
|
||||||
|
|
||||||
proc ParseUnit*(p: var TParser): PNode
|
proc ParseUnit*(p: var TParser): PNode
|
||||||
|
|
@ -234,22 +237,22 @@ proc getTok(p: var TParser, n: PNode) =
|
||||||
getTok(p)
|
getTok(p)
|
||||||
skipCom(p, n)
|
skipCom(p, n)
|
||||||
|
|
||||||
proc ExpectIdent(p: TParser) =
|
proc expectIdent(p: TParser) =
|
||||||
if p.tok.xkind != pxSymbol: parMessage(p, errIdentifierExpected, $(p.tok[]))
|
if p.tok.xkind != pxSymbol: parMessage(p, errIdentifierExpected, $(p.tok[]))
|
||||||
|
|
||||||
proc Eat(p: var TParser, xkind: TTokKind, n: PNode) =
|
proc eat(p: var TParser, xkind: TTokKind, n: PNode) =
|
||||||
if p.tok.xkind == xkind: getTok(p, n)
|
if p.tok.xkind == xkind: getTok(p, n)
|
||||||
else: parMessage(p, errTokenExpected, TokKindToStr(xkind))
|
else: parMessage(p, errTokenExpected, TokKindToStr(xkind))
|
||||||
|
|
||||||
proc Eat(p: var TParser, xkind: TTokKind) =
|
proc eat(p: var TParser, xkind: TTokKind) =
|
||||||
if p.tok.xkind == xkind: getTok(p)
|
if p.tok.xkind == xkind: getTok(p)
|
||||||
else: parMessage(p, errTokenExpected, TokKindToStr(xkind))
|
else: parMessage(p, errTokenExpected, TokKindToStr(xkind))
|
||||||
|
|
||||||
proc Eat(p: var TParser, tok: string, n: PNode) =
|
proc eat(p: var TParser, tok: string, n: PNode) =
|
||||||
if p.tok.s == tok: getTok(p, n)
|
if p.tok.s == tok: getTok(p, n)
|
||||||
else: parMessage(p, errTokenExpected, tok)
|
else: parMessage(p, errTokenExpected, tok)
|
||||||
|
|
||||||
proc Opt(p: var TParser, xkind: TTokKind, n: PNode) =
|
proc opt(p: var TParser, xkind: TTokKind, n: PNode) =
|
||||||
if p.tok.xkind == xkind: getTok(p, n)
|
if p.tok.xkind == xkind: getTok(p, n)
|
||||||
|
|
||||||
proc addSon(father, a, b: PNode) =
|
proc addSon(father, a, b: PNode) =
|
||||||
|
|
@ -361,11 +364,11 @@ proc fieldIdent(ident: string, p: TParser): PNode =
|
||||||
addSon(result, pragmas)
|
addSon(result, pragmas)
|
||||||
addSon(pragmas, newIdentStrLitPair("importc", ident, p))
|
addSon(pragmas, newIdentStrLitPair("importc", ident, p))
|
||||||
|
|
||||||
proc DoImport(ident: string, pragmas: PNode, p: TParser) =
|
proc doImport(ident: string, pragmas: PNode, p: TParser) =
|
||||||
if p.options.dynlibSym.len > 0 or p.options.header.len > 0:
|
if p.options.dynlibSym.len > 0 or p.options.header.len > 0:
|
||||||
addImportToPragma(pragmas, ident, p)
|
addImportToPragma(pragmas, ident, p)
|
||||||
|
|
||||||
proc DoImportCpp(ident: string, pragmas: PNode, p: TParser) =
|
proc doImportCpp(ident: string, pragmas: PNode, p: TParser) =
|
||||||
if p.options.dynlibSym.len > 0 or p.options.header.len > 0:
|
if p.options.dynlibSym.len > 0 or p.options.header.len > 0:
|
||||||
addSon(pragmas, newIdentStrLitPair("importcpp", ident, p))
|
addSon(pragmas, newIdentStrLitPair("importcpp", ident, p))
|
||||||
if p.options.dynlibSym.len > 0:
|
if p.options.dynlibSym.len > 0:
|
||||||
|
|
@ -505,9 +508,21 @@ proc optAngle(p: var TParser, n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
result = n
|
result = n
|
||||||
|
|
||||||
|
proc optScope(p: var TParser, n: PNode): PNode =
|
||||||
|
result = n
|
||||||
|
if pfCpp in p.options.flags:
|
||||||
|
while p.tok.xkind == pxScope:
|
||||||
|
let a = result
|
||||||
|
result = newNodeP(nkDotExpr, p)
|
||||||
|
result.add(a)
|
||||||
|
getTok(p, result)
|
||||||
|
expectIdent(p)
|
||||||
|
result.add(mangledIdent(p.tok.s, p))
|
||||||
|
getTok(p, result)
|
||||||
|
|
||||||
proc typeAtom(p: var TParser): PNode =
|
proc typeAtom(p: var TParser): PNode =
|
||||||
skipConst(p)
|
skipConst(p)
|
||||||
ExpectIdent(p)
|
expectIdent(p)
|
||||||
case p.tok.s
|
case p.tok.s
|
||||||
of "void":
|
of "void":
|
||||||
result = newNodeP(nkNilLit, p) # little hack
|
result = newNodeP(nkNilLit, p) # little hack
|
||||||
|
|
@ -533,6 +548,7 @@ proc typeAtom(p: var TParser): PNode =
|
||||||
else:
|
else:
|
||||||
result = mangledIdent(p.tok.s, p)
|
result = mangledIdent(p.tok.s, p)
|
||||||
getTok(p, result)
|
getTok(p, result)
|
||||||
|
result = optScope(p, result)
|
||||||
result = optAngle(p, result)
|
result = optAngle(p, result)
|
||||||
|
|
||||||
proc newPointerTy(p: TParser, typ: PNode): PNode =
|
proc newPointerTy(p: TParser, typ: PNode): PNode =
|
||||||
|
|
@ -1017,6 +1033,7 @@ proc declaration(p: var TParser): PNode =
|
||||||
if pfCpp in p.options.flags and p.tok.xkind == pxSymbol and
|
if pfCpp in p.options.flags and p.tok.xkind == pxSymbol and
|
||||||
p.tok.s == "const":
|
p.tok.s == "const":
|
||||||
addSon(pragmas, newIdentNodeP("noSideEffect", p))
|
addSon(pragmas, newIdentNodeP("noSideEffect", p))
|
||||||
|
getTok(p)
|
||||||
if pfCDecl in p.options.flags:
|
if pfCDecl in p.options.flags:
|
||||||
addSon(pragmas, newIdentNodeP("cdecl", p))
|
addSon(pragmas, newIdentNodeP("cdecl", p))
|
||||||
elif pfStdcall in p.options.flags:
|
elif pfStdcall in p.options.flags:
|
||||||
|
|
@ -1169,6 +1186,7 @@ proc primaryExpression(p: var TParser): PNode =
|
||||||
else:
|
else:
|
||||||
result = mangledIdent(p.tok.s, p)
|
result = mangledIdent(p.tok.s, p)
|
||||||
getTok(p, result)
|
getTok(p, result)
|
||||||
|
result = optScope(p, result)
|
||||||
of pxIntLit:
|
of pxIntLit:
|
||||||
result = newIntNodeP(nkIntLit, p.tok.iNumber, p)
|
result = newIntNodeP(nkIntLit, p.tok.iNumber, p)
|
||||||
setBaseFlags(result, p.tok.base)
|
setBaseFlags(result, p.tok.base)
|
||||||
|
|
@ -1925,7 +1943,7 @@ proc parseClass(p: var TParser; isStruct: bool; stmtList: PNode): PNode =
|
||||||
getTok(p, result)
|
getTok(p, result)
|
||||||
eat(p, pxColon, result)
|
eat(p, pxColon, result)
|
||||||
private = false
|
private = false
|
||||||
if p.tok.xkind == pxSymbol and p.tok.s == "friend":
|
if p.tok.xkind == pxSymbol and (p.tok.s == "friend" or p.tok.s == "using"):
|
||||||
# we skip friend declarations:
|
# we skip friend declarations:
|
||||||
while p.tok.xkind notin {pxEof, pxSemicolon}: getTok(p)
|
while p.tok.xkind notin {pxEof, pxSemicolon}: getTok(p)
|
||||||
eat(p, pxSemicolon)
|
eat(p, pxSemicolon)
|
||||||
|
|
@ -2012,7 +2030,9 @@ proc parseStandaloneClass(p: var TParser, isStruct: bool): PNode =
|
||||||
else:
|
else:
|
||||||
p.currentClass = nil
|
p.currentClass = nil
|
||||||
if p.tok.xkind in {pxCurlyLe, pxSemiColon, pxColon}:
|
if p.tok.xkind in {pxCurlyLe, pxSemiColon, pxColon}:
|
||||||
if origName.len > 0:
|
if origName.len > 0:
|
||||||
|
p.options.classes[origName] = "true"
|
||||||
|
|
||||||
var typeSection = newNodeP(nkTypeSection, p)
|
var typeSection = newNodeP(nkTypeSection, p)
|
||||||
addSon(result, typeSection)
|
addSon(result, typeSection)
|
||||||
|
|
||||||
|
|
@ -2092,6 +2112,13 @@ proc statement(p: var TParser): PNode =
|
||||||
result = compoundStatement(p)
|
result = compoundStatement(p)
|
||||||
else:
|
else:
|
||||||
result = declarationOrStatement(p)
|
result = declarationOrStatement(p)
|
||||||
|
of "using":
|
||||||
|
if pfCpp in p.options.flags:
|
||||||
|
while p.tok.xkind notin {pxEof, pxSemicolon}: getTok(p)
|
||||||
|
eat(p, pxSemicolon)
|
||||||
|
result = newNodeP(nkNilLit, p)
|
||||||
|
else:
|
||||||
|
result = declarationOrStatement(p)
|
||||||
else: result = declarationOrStatement(p)
|
else: result = declarationOrStatement(p)
|
||||||
of pxCurlyLe:
|
of pxCurlyLe:
|
||||||
result = compoundStatement(p)
|
result = compoundStatement(p)
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,7 @@ proc parseDir(p: var TParser): PNode =
|
||||||
discard setOption(p.options, p.tok.s)
|
discard setOption(p.options, p.tok.s)
|
||||||
getTok(p)
|
getTok(p)
|
||||||
eatNewLine(p, nil)
|
eatNewLine(p, nil)
|
||||||
of "dynlib", "header", "prefix", "suffix":
|
of "dynlib", "header", "prefix", "suffix", "class":
|
||||||
var key = p.tok.s
|
var key = p.tok.s
|
||||||
getTok(p)
|
getTok(p)
|
||||||
if p.tok.xkind != pxStrLit: ExpectIdent(p)
|
if p.tok.xkind != pxStrLit: ExpectIdent(p)
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ public:
|
||||||
|
|
||||||
void operator = (const wxTransformMatrix& mat);
|
void operator = (const wxTransformMatrix& mat);
|
||||||
bool operator == (const wxTransformMatrix& mat) const;
|
bool operator == (const wxTransformMatrix& mat) const;
|
||||||
bool operator != (const wxTransformMatrix& mat) const;
|
bool operator != (const module::gah::wxTransformMatrix& mat) const;
|
||||||
|
|
||||||
//multiply every element by t
|
//multiply every element by t
|
||||||
wxTransformMatrix& operator*=(const double& t);
|
wxTransformMatrix& operator*=(const double& t);
|
||||||
|
|
@ -184,7 +184,7 @@ public:
|
||||||
Chris Breeze reported, that
|
Chris Breeze reported, that
|
||||||
some functions of wxTransformMatrix cannot work because it is not
|
some functions of wxTransformMatrix cannot work because it is not
|
||||||
known if he matrix has been inverted. Be careful when using it.
|
known if he matrix has been inverted. Be careful when using it.
|
||||||
|
*/
|
||||||
|
|
||||||
// Transform X value from logical to device
|
// Transform X value from logical to device
|
||||||
// warning: this function can only be used for this purpose
|
// warning: this function can only be used for this purpose
|
||||||
|
|
@ -235,7 +235,6 @@ inline bool wxTransformMatrix::IsIdentity1(void) const
|
||||||
inline double wxCalculateDet(double a11, double a21, double a12, double a22)
|
inline double wxCalculateDet(double a11, double a21, double a12, double a22)
|
||||||
{
|
{
|
||||||
return a11 * a22 - a12 * a21;
|
return a11 * a22 - a12 * a21;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
#endif // _WX_MATRIXH__
|
#endif // _WX_MATRIXH__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue