diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2008-08-23 11:32:48 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2008-08-23 11:32:48 +0200 |
commit | 972c51086152bd45aef4eb17c099fa3472a19d04 (patch) | |
tree | 3e51e4f71f737a4f943bb71cd889d7002c3d4b5a /lib/macros.nim | |
parent | 07d5a8085bbcc21a1d9d06a2976ecc00e9c8d55b (diff) | |
download | Nim-972c51086152bd45aef4eb17c099fa3472a19d04.tar.gz |
deleted web and dist
Diffstat (limited to 'lib/macros.nim')
-rw-r--r-- | lib/macros.nim | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/lib/macros.nim b/lib/macros.nim new file mode 100644 index 000000000..af5e0d17d --- /dev/null +++ b/lib/macros.nim @@ -0,0 +1,176 @@ +# +# +# Nimrod's Runtime Library +# (c) Copyright 2008 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + + +## This module contains the interface to the compiler's abstract syntax tree. +## Abstract syntax trees should be modified in macros. + +#[[[cog +#def toEnum(name, elems, prefix): +# body = "" +# counter = 0 +# for e in elems: +# if counter % 4 == 0: p = "\n " +# else: p = "" +# body += p + prefix + e[2:] + ', ' +# counter += 1 +# +# return " TNimrod%s* = enum%s\n TNim%ss* = set[TNimrod%s]\n" \ +# % (name, body.rstrip(", "), name, name) +# +#enums = eval(file("data/ast.yml").read()) +#cog.out("type\n") +#i = 0 +#for key, val in enums.iteritems(): +# if key.endswith("Flag"): continue +# cog.out(toEnum(key, val, ["nnk", "nty", "nsk"][i])) +# i += 1 +#]]] +type + TNimrodNodeKind* = enum + nnkNone, nnkEmpty, nnkIdent, nnkSym, + nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit, + nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkFloatLit, + nnkFloat32Lit, nnkFloat64Lit, nnkStrLit, nnkRStrLit, + nnkTripleStrLit, nnkMetaNode, nnkNilLit, nnkDotCall, + nnkCommand, nnkCall, nnkGenericCall, nnkExplicitTypeListCall, + nnkExprEqExpr, nnkExprColonExpr, nnkIdentDefs, nnkInfix, + nnkPrefix, nnkPostfix, nnkPar, nnkCurly, + nnkBracket, nnkBracketExpr, nnkPragmaExpr, nnkRange, + nnkDotExpr, nnkCheckedFieldExpr, nnkDerefExpr, nnkIfExpr, + nnkElifExpr, nnkElseExpr, nnkLambda, nnkAccQuoted, + nnkHeaderQuoted, nnkTableConstr, nnkQualified, nnkHiddenStdConv, + nnkHiddenSubConv, nnkHiddenCallConv, nnkConv, nnkCast, + nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv, + nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange, + nnkStringToCString, nnkCStringToString, nnkPassAsOpenArray, nnkAsgn, + nnkDefaultTypeParam, nnkGenericParams, nnkFormalParams, nnkOfInherit, + nnkModule, nnkProcDef, nnkConverterDef, nnkMacroDef, + nnkTemplateDef, nnkIteratorDef, nnkOfBranch, nnkElifBranch, + nnkExceptBranch, nnkElse, nnkMacroStmt, nnkAsmStmt, + nnkPragma, nnkIfStmt, nnkWhenStmt, nnkForStmt, + nnkWhileStmt, nnkCaseStmt, nnkVarSection, nnkConstSection, + nnkConstDef, nnkTypeSection, nnkTypeDef, nnkYieldStmt, + nnkTryStmt, nnkFinally, nnkRaiseStmt, nnkReturnStmt, + nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkDiscardStmt, + nnkStmtList, nnkImportStmt, nnkFromStmt, nnkImportAs, + nnkIncludeStmt, nnkAccessStmt, nnkCommentStmt, nnkStmtListExpr, + nnkBlockExpr, nnkVm, nnkTypeOfExpr, nnkObjectTy, + nnkTupleTy, nnkRecList, nnkRecCase, nnkRecWhen, + nnkRefTy, nnkPtrTy, nnkVarTy, nnkProcTy, + nnkEnumTy, nnkEnumFieldDef, nnkReturnToken + TNimNodeKinds* = set[TNimrodNodeKind] + TNimrodTypeKind* = enum + ntyNone, ntyBool, ntyChar, ntyEmptySet, + ntyArrayConstr, ntyNil, ntyGeneric, ntyGenericInst, + ntyGenericParam, ntyEnum, ntyAnyEnum, ntyArray, + ntyObject, ntyTuple, ntySet, ntyRange, + ntyPtr, ntyRef, ntyVar, ntySequence, + ntyProc, ntyPointer, ntyOpenArray, ntyString, + ntyCString, ntyForward, ntyInt, ntyInt8, + ntyInt16, ntyInt32, ntyInt64, ntyFloat, + ntyFloat32, ntyFloat64, ntyFloat128 + TNimTypeKinds* = set[TNimrodTypeKind] + TNimrodSymKind* = enum + nskUnknownSym, nskConditional, nskDynLib, nskParam, + nskTypeParam, nskTemp, nskType, nskConst, + nskVar, nskProc, nskIterator, nskConverter, + nskMacro, nskTemplate, nskField, nskEnumField, + nskForVar, nskModule, nskLabel + TNimSymKinds* = set[TNimrodSymKind] +#[[[end]]] + +type + TNimrodNode {.final.} = object # hidden + TNimrodSymbol {.final.} = object # hidden + TNimrodType {.final.} = object # hidden + PNimrodType* {.compilerproc.} = ref TNimrodType + PNimrodSymbol* {.compilerproc.} = ref TNimrodSymbol + PNimrodNode* {.compilerproc.} = ref TNimrodNode + expr* = PNimrodNode + stmt* = PNimrodNode + +# Nodes should be reference counted to make the `copy` operation very fast! +# However, this is difficult to achieve: modify(n[0][1]) should propagate to +# its father. How to do this without back references? + +proc `[]`* (n: PNimrodNode, i: int): PNimrodNode {.magic: "NChild".} +proc `[]=`* (n: PNimrodNode, i: int, child: PNimrodNode) {.magic: "NSetChild".} + ## provide access to `n`'s children + +type + TNimrodIdent = object of TObject + +converter StrToIdent*(s: string): TNimrodIdent {.magic: "StrToIdent".} +proc `$`*(i: TNimrodIdent): string {.magic: "IdentToStr".} +proc `==`* (a, b: TNimrodIdent): bool {.magic: "EqIdent".} + +proc len*(n: PNimrodNode): int {.magic: "NLen".} + +## returns the number of children that a node has +proc add*(father, child: PNimrodNode) {.magic: "NAdd".} +proc add*(father: PNimrodNode, child: openArray[PNimrodNode]) {.magic: "NAddMultiple".} +proc del*(father: PNimrodNode, idx = 0, n = 1) {.magic: "NDel".} +proc kind*(n: PNimrodNode): TNimrodNodeKind {.magic: "NKind".} + +proc intVal*(n: PNimrodNode): biggestInt {.magic: "NIntVal".} +proc floatVal*(n: PNimrodNode): biggestFloat {.magic: "NFloatVal".} +proc symbol*(n: PNimrodNode): PNimrodSymbol {.magic: "NSymbol".} +proc ident*(n: PNimrodNode): TNimrodIdent {.magic: "NIdent".} +proc typ*(n: PNimrodNode): PNimrodType {.magic: "NGetType".} +proc strVal*(n: PNimrodNode): string {.magic: "NStrVal".} + +proc `intVal=`*(n: PNimrodNode, val: biggestInt) {.magic: "NSetIntVal".} +proc `floatVal=`*(n: PNimrodNode, val: biggestFloat) {.magic: "NSetFloatVal".} +proc `symbol=`*(n: PNimrodNode, val: PNimrodSymbol) {.magic: "NSetSymbol".} +proc `ident=`*(n: PNimrodNode, val: TNimrodIdent) {.magic: "NSetIdent".} +proc `typ=`*(n: PNimrodNode, typ: PNimrodType) {.magic: "NSetType".} +proc `strVal=`*(n: PNimrodNode, val: string) {.magic: "NSetStrVal".} + +proc newNimNode*(kind: TNimrodNodeKind, + n: PNimrodNode=nil): PNimrodNode {.magic: "NNewNimNode".} +proc copyNimNode*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimNode".} +proc copyNimTree*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimTree".} + +proc error*(msg: string) {.magic: "NError".} +proc warning*(msg: string) {.magic: "NWarning".} +proc hint*(msg: string) {.magic: "NHint".} + +proc newStrLitNode*(s: string): PNimrodNode {.nodecl.} = + result = newNimNode(nnkStrLit) + result.strVal = s + +proc newIntLitNode*(i: biggestInt): PNimrodNode {.nodecl.} = + result = newNimNode(nnkIntLit) + result.intVal = i + +proc newIntLitNode*(f: biggestFloat): PNimrodNode {.nodecl.} = + result = newNimNode(nnkFloatLit) + result.floatVal = f + +proc newIdentNode*(i: TNimrodIdent): PNimrodNode {.nodecl.} = + result = newNimNode(nnkIdent) + result.ident = i + +proc toStrLit*(n: PNimrodNode): PNimrodNode {.nodecl.} = + return newStrLitNode(repr(n)) + +proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.nodecl.} = + if n.kind != k: error("macro expects a node of kind: " & repr(k)) + +proc expectMinLen*(n: PNimrodNode, min: int) {.nodecl.} = + if n.len < min: error("macro expects a node with " & $min & " children") + +proc newCall*(theProc: TNimrodIdent, + args: openArray[PNimrodNode]): PNimrodNode {.nodecl.} = + ## produces a new call node. `theProc` is the proc that is called with + ## the arguments ``args[0..]``. + result = newNimNode(nnkCall) + result.add(newIdentNode(theProc)) + result.add(args) |