version 0.7.6

This commit is contained in:
Andreas Rumpf 2009-04-22 15:55:27 +02:00
commit e792940f52
106 changed files with 8394 additions and 10083 deletions

View file

@ -58,12 +58,12 @@ type
nnkTypeDef, nnkYieldStmt, nnkTryStmt, nnkFinally,
nnkRaiseStmt, nnkReturnStmt, nnkBreakStmt, nnkContinueStmt,
nnkBlockStmt, nnkDiscardStmt, nnkStmtList, nnkImportStmt,
nnkFromStmt, nnkImportAs, nnkIncludeStmt, nnkAccessStmt,
nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr, nnkStmtListType,
nnkBlockType, nnkVm, nnkTypeOfExpr, nnkObjectTy,
nnkTupleTy, nnkRecList, nnkRecCase, nnkRecWhen,
nnkRefTy, nnkPtrTy, nnkVarTy, nnkProcTy,
nnkEnumTy, nnkEnumFieldDef, nnkReturnToken
nnkFromStmt, nnkImportAs, nnkIncludeStmt, nnkCommentStmt,
nnkStmtListExpr, nnkBlockExpr, nnkStmtListType, nnkBlockType,
nnkVm, nnkTypeOfExpr, nnkObjectTy, nnkTupleTy,
nnkRecList, nnkRecCase, nnkRecWhen, nnkRefTy,
nnkPtrTy, nnkVarTy, nnkProcTy, nnkEnumTy,
nnkEnumFieldDef, nnkReturnToken
TNimNodeKinds* = set[TNimrodNodeKind]
TNimrodTypeKind* = enum
ntyNone, ntyBool, ntyChar, ntyEmpty,
@ -86,12 +86,24 @@ type
#[[[end]]]
type
TNimrodIdent = object of TObject
## represents a Nimrod identifier in the AST
TNimrodNode {.final.} = object # hidden
TNimrodSymbol {.final.} = object # hidden
TNimrodType {.final.} = object # hidden
PNimrodType* {.compilerproc.} = ref TNimrodType
## represents a Nimrod type in the compiler; currently this is not very
## useful as there is no API to deal with Nimrod types.
PNimrodSymbol* {.compilerproc.} = ref TNimrodSymbol
## represents a Nimrod *symbol* in the compiler; a *symbol* is a looked-up
## *ident*.
PNimrodNode* {.compilerproc.} = ref TNimrodNode
## represents a Nimrod AST node. Macros operate on this type.
expr* = PNimrodNode
stmt* = PNimrodNode
@ -100,23 +112,35 @@ type
# its father. How to do this without back references?
proc `[]`* (n: PNimrodNode, i: int): PNimrodNode {.magic: "NChild".}
## get `n`'s `i`'th child.
proc `[]=`* (n: PNimrodNode, i: int, child: PNimrodNode) {.magic: "NSetChild".}
## provide access to `n`'s children
## set `n`'s `i`'th child to `child`.
type
TNimrodIdent = object of TObject
proc `!` *(s: string): TNimrodIdent {.magic: "StrToIdent".}
## constructs an identifier from the string `s`
converter StrToIdent*(s: string): TNimrodIdent {.magic: "StrToIdent".}
proc `$`*(i: TNimrodIdent): string {.magic: "IdentToStr".}
## converts a Nimrod identifier to a string
proc `==`* (a, b: TNimrodIdent): bool {.magic: "EqIdent".}
## compares two Nimrod identifiers
proc len*(n: PNimrodNode): int {.magic: "NLen".}
## returns the number of children of `n`.
## 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".}
## adds the `child` to the `father` node
proc add*(father: PNimrodNode, children: openArray[PNimrodNode]) {.
magic: "NAddMultiple".}
## adds each `children` to the `father` node
proc del*(father: PNimrodNode, idx = 0, n = 1) {.magic: "NDel".}
## deletes `n` children of `father` starting at index `idx`.
proc kind*(n: PNimrodNode): TNimrodNodeKind {.magic: "NKind".}
## returns the `kind` of the node `n`.
proc intVal*(n: PNimrodNode): biggestInt {.magic: "NIntVal".}
proc floatVal*(n: PNimrodNode): biggestFloat {.magic: "NFloatVal".}
@ -133,43 +157,81 @@ 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".}
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".}
## writes an error message at compile time
proc warning*(msg: string) {.magic: "NWarning".}
## writes a warning message at compile time
proc hint*(msg: string) {.magic: "NHint".}
## writes a hint message at compile time
proc newStrLitNode*(s: string): PNimrodNode {.compileTime.} =
## creates a string literal node from `s`
result = newNimNode(nnkStrLit)
result.strVal = s
proc newIntLitNode*(i: biggestInt): PNimrodNode {.compileTime.} =
## creates a int literal node from `i`
result = newNimNode(nnkIntLit)
result.intVal = i
proc newIntLitNode*(f: biggestFloat): PNimrodNode {.compileTime.} =
proc newFloatLitNode*(f: biggestFloat): PNimrodNode {.compileTime.} =
## creates a float literal node from `f`
result = newNimNode(nnkFloatLit)
result.floatVal = f
proc newIdentNode*(i: TNimrodIdent): PNimrodNode {.compileTime.} =
## creates an identifier node from `i`
result = newNimNode(nnkIdent)
result.ident = i
proc newIdentNode*(i: string): PNimrodNode {.compileTime.} =
## creates an identifier node from `i`
result = newNimNode(nnkIdent)
result.ident = !i
proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} =
## converts the AST `n` to the concrete Nimrod code and wraps that
## in a string literal node
return newStrLitNode(repr(n))
proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.compileTime.} =
## checks that `n` is of kind `k`. If this is not the case,
## compilation aborts with an error message. This is useful for writing
## macros that check the AST that is passed to them.
if n.kind != k: error("macro expects a node of kind: " & repr(k))
proc expectMinLen*(n: PNimrodNode, min: int) {.compileTime.} =
## checks that `n` has at least `min` children. If this is not the case,
## compilation aborts with an error message. This is useful for writing
## macros that check its number of arguments.
if n.len < min: error("macro expects a node with " & $min & " children")
proc expectLen*(n: PNimrodNode, len: int) {.compileTime.} =
## checks that `n` has exactly `len` children. If this is not the case,
## compilation aborts with an error message. This is useful for writing
## macros that check its number of arguments.
if n.len != len: error("macro expects a node with " & $len & " children")
proc newCall*(theProc: TNimrodIdent,
args: openArray[PNimrodNode]): PNimrodNode {.compileTime.} =
## 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)
proc newCall*(theProc: string,
args: openArray[PNimrodNode]): PNimrodNode {.compileTime.} =
## 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)