Add missing file
This commit is contained in:
parent
f2a23b8b77
commit
f7f6ae052f
|
@ -0,0 +1,317 @@
|
|||
import errors
|
||||
import frontend/parsing/parser
|
||||
|
||||
|
||||
import std/tables
|
||||
|
||||
|
||||
export ast, errors
|
||||
|
||||
|
||||
|
||||
type
|
||||
IntegerSize* = enum
|
||||
## Integer size enumeration
|
||||
Tiny = 8
|
||||
Short = 16
|
||||
Long = 32
|
||||
LongLong = 64
|
||||
|
||||
FloatSize* = enum
|
||||
## Float size enumeration
|
||||
Half = 32
|
||||
Full = 64
|
||||
|
||||
TypeKind* = enum
|
||||
## Enumeration of compile-time types
|
||||
Integer,
|
||||
Float,
|
||||
String,
|
||||
NaN,
|
||||
Infinity,
|
||||
Boolean,
|
||||
Any,
|
||||
Typevar,
|
||||
Auto,
|
||||
Byte,
|
||||
Char,
|
||||
Nil,
|
||||
CustomType,
|
||||
EnumEntry,
|
||||
Reference,
|
||||
Pointer,
|
||||
Generic,
|
||||
Union,
|
||||
Function,
|
||||
Lent,
|
||||
Const
|
||||
|
||||
Type* = ref object
|
||||
## A compile-time type
|
||||
|
||||
# Is this type a compiler intrinsic?
|
||||
intrinsic*: bool
|
||||
# Is this a type constant?
|
||||
constant*: bool
|
||||
# Can this value be mutated?
|
||||
mutable*: bool
|
||||
case kind*: TypeKind
|
||||
of Integer:
|
||||
signed*: bool
|
||||
size*: IntegerSize
|
||||
of Float:
|
||||
width*: FloatSize
|
||||
of Infinity:
|
||||
positive*: bool
|
||||
of Function:
|
||||
isLambda*: bool
|
||||
isGenerator*: bool
|
||||
isCoroutine*: bool
|
||||
isAuto*: bool
|
||||
args*: TypeSignature
|
||||
returnType*: Type
|
||||
builtinOp*: string
|
||||
fun*: Declaration
|
||||
forwarded*: bool
|
||||
genericArgs*: TableRef[string, Type]
|
||||
safe*: bool
|
||||
of Typevar:
|
||||
wrapped*: Type
|
||||
of CustomType:
|
||||
typeName*: string
|
||||
generics*: TableRef[string, Type]
|
||||
fields*: TableRef[string, Type]
|
||||
parent*: Type
|
||||
interfaces*: seq[Type]
|
||||
isEnum*: bool
|
||||
of Reference, Pointer, Lent, Const:
|
||||
value*: Type
|
||||
of Generic:
|
||||
# cond represents a type constraint. For
|
||||
# example, fn foo[T*: int & ~uint](...) {...}
|
||||
# would map to [(true, int), (false, uint)]
|
||||
cond*: seq[tuple[match: bool, kind: Type, value: Expression]]
|
||||
asUnion*: bool # If this is true, the constraint is treated like a type union
|
||||
name*: string
|
||||
of Union:
|
||||
types*: seq[tuple[match: bool, kind: Type, value: Expression]]
|
||||
else:
|
||||
discard
|
||||
|
||||
WarningKind* {.pure.} = enum
|
||||
## A warning enumeration type
|
||||
UserWarning
|
||||
|
||||
NameKind* {.pure.} = enum
|
||||
## A name enumeration type
|
||||
None, Module, Argument, Var, Function, CustomType, Enum
|
||||
|
||||
Name* = ref object
|
||||
## A generic name object
|
||||
|
||||
# Type of the identifier (NOT of the value!)
|
||||
case kind*: NameKind
|
||||
of Module:
|
||||
path*: string
|
||||
# Full absolute path of the module,
|
||||
# including the extension
|
||||
absPath*: string
|
||||
# Just for easier lookup, it's all
|
||||
# pointers anyway
|
||||
names*: TableRef[string, Name]
|
||||
of NameKind.Var:
|
||||
# If the variable's value is another
|
||||
# name, this attribute contains its
|
||||
# name object. This is useful for things
|
||||
# like assigning functions to variables and
|
||||
# then calling the variable like it's the
|
||||
# original function
|
||||
assignedName*: Name
|
||||
else:
|
||||
discard
|
||||
# The name's identifier
|
||||
ident*: IdentExpr
|
||||
# Owner of the identifier (module)
|
||||
owner*: Name
|
||||
# File where the name is declared
|
||||
file*: string
|
||||
# Scope depth
|
||||
depth*: int
|
||||
# Is this name private?
|
||||
isPrivate*: bool
|
||||
# Is this name a generic type?
|
||||
isGeneric*: bool
|
||||
# The type of the name's associated
|
||||
# value
|
||||
valueType*: Type
|
||||
# The function that owns this name (may be nil!)
|
||||
belongsTo*: Name
|
||||
# Where is this node declared in its file?
|
||||
line*: int
|
||||
# The AST node associated with this node. This
|
||||
# is needed because we tyoecheck function and type
|
||||
# declarations only if, and when, they're actually
|
||||
# used
|
||||
node*: Declaration
|
||||
# Who is this name exported to? (Only makes sense if isPrivate
|
||||
# equals false)
|
||||
exportedTo*: seq[Name]
|
||||
# Is this name generated by user code or internally by the type checker?
|
||||
isReal*: bool
|
||||
|
||||
TypeSignature* = seq[tuple[name: string, kind: Type, default: TypedExpr]]
|
||||
|
||||
## Our typed AST representation
|
||||
|
||||
TypedNode* = ref object of RootObj
|
||||
## A generic typed AST node
|
||||
node*: ASTNode
|
||||
|
||||
TypedExpr* = ref object of TypedNode
|
||||
## A generic typed expression
|
||||
kind*: Type
|
||||
|
||||
TypedUnaryExpr* = ref object of TypedExpr
|
||||
## A generic typed unary expression
|
||||
a*: TypedExpr
|
||||
|
||||
TypedBinaryExpr* = ref object of TypedUnaryExpr
|
||||
## A generic typed binary expression
|
||||
b*: TypedExpr
|
||||
|
||||
TypedIdentExpr* = ref object of TypedExpr
|
||||
## A typed identifier expression
|
||||
name*: Name
|
||||
|
||||
TypedCallExpr* = ref object of TypedExpr
|
||||
## A typed function call expression
|
||||
callee*: Name
|
||||
args*: seq[tuple[name: string, kind: Type, default: TypedExpr]]
|
||||
|
||||
TypedDecl* = ref object of TypedNode
|
||||
## A typed declaration node
|
||||
name*: Name # The declaration's name object
|
||||
|
||||
TypedVarDecl* = ref object of TypedDecl
|
||||
## A typed variable declaration node
|
||||
init*: TypedExpr
|
||||
|
||||
TypedTypeDecl* = ref object of TypedDecl
|
||||
## A typed type declaration node
|
||||
fields*: TableRef[string, TypedExpr]
|
||||
parent*: Name
|
||||
interfaces*: seq[TypedTypeDecl]
|
||||
|
||||
TypedEnumDecl* = ref object of TypedTypeDecl
|
||||
## A typed enum declaration node
|
||||
enumeration*: Type
|
||||
variants: seq[TypedTypeDecl]
|
||||
|
||||
TypedFunDecl* = ref object of TypedDecl
|
||||
## A typed function declaration
|
||||
args*: seq[tuple[name: Name, default: TypedExpr]]
|
||||
body*: TypedBlockStmt
|
||||
|
||||
TypedStmt* = ref object of TypedNode
|
||||
## A typed statement node
|
||||
|
||||
TypedBlockStmt* = ref object of TypedStmt
|
||||
## A typed block statement
|
||||
body*: seq[TypedNode]
|
||||
|
||||
TypedIfStmt* = ref object of TypedStmt
|
||||
## A typed if statement node
|
||||
thenBranch*: TypedBlockStmt
|
||||
elseBranch*: TypedBlockStmt
|
||||
condition*: TypedExpr
|
||||
|
||||
TypedWhileStmt* = ref object of TypedStmt
|
||||
## A typed while statement node
|
||||
body*: TypedBlockStmt
|
||||
condition*: TypedExpr
|
||||
|
||||
|
||||
proc newTypedNode*(node: ASTNode): TypedNode =
|
||||
## Initializes a new typed node
|
||||
new(result)
|
||||
result.node = node
|
||||
|
||||
|
||||
proc newTypedExpr*(node: Expression, kind: Type): TypedExpr =
|
||||
## Initializes a new typed expression
|
||||
result = TypedExpr(node: node, kind: kind)
|
||||
|
||||
|
||||
proc newTypedDecl*(node: Declaration, name: Name): TypedDecl =
|
||||
## Initializes a new typed declaration
|
||||
result = TypedDecl(node: node, name: name)
|
||||
|
||||
|
||||
proc newTypedTypeDecl*(node: TypeDecl, name: Name, fields: TableRef[string, TypedExpr], parent: Name): TypedTypeDecl =
|
||||
## Initializes a new typed function declaration
|
||||
result = TypedTypeDecl(node: node, name: name, fields: fields, parent: parent)
|
||||
|
||||
|
||||
proc newTypedEnumDecl*(node: TypeDecl, name: Name, variants: seq[TypedTypeDecl], enumeration: Type): TypedEnumDecl =
|
||||
## Initializes a new typed function declaration
|
||||
result = TypedEnumDecl(node: node, name: name, variants: variants, enumeration: enumeration)
|
||||
|
||||
|
||||
proc newTypedFunDecl*(node: FunDecl, name: Name, body: TypedBlockStmt): TypedFunDecl =
|
||||
## Initializes a new typed function declaration
|
||||
result = TypedFunDecl(node: node, name: name, body: body)
|
||||
|
||||
|
||||
proc newTypedVarDecl*(node: VarDecl, name: Name, init: TypedExpr): TypedVarDecl =
|
||||
## Initializes a new typed function declaration
|
||||
result = TypedVarDecl(node: node, name: name, init: init)
|
||||
|
||||
|
||||
proc newTypedIdentExpr*(node: IdentExpr, name: Name): TypedIdentExpr =
|
||||
## Initializes a new typed identifier expression
|
||||
result = TypedIdentExpr(node: node, name: name, kind: name.valueType)
|
||||
|
||||
|
||||
proc newTypedUnaryExpr*(node: UnaryExpr, kind: Type, a: TypedExpr): TypedUnaryExpr =
|
||||
## Initializes a new typed unary expression
|
||||
result = TypedUnaryExpr(node: node, a: a, kind: kind)
|
||||
|
||||
|
||||
proc newTypedBinaryExpr*(node: UnaryExpr, kind: Type, a, b: TypedExpr): TypedBinaryExpr =
|
||||
## Initializes a new typed binary expression
|
||||
result = TypedBinaryExpr(node: node, a: a, b: b, kind: kind)
|
||||
|
||||
|
||||
proc newTypedCallExpr*(node: CallExpr, callee: Name,
|
||||
args: seq[tuple[name: string, kind: Type, default: TypedExpr]]): TypedCallExpr =
|
||||
|
||||
## Initializes a new typed function call expression
|
||||
result = TypedCallExpr(node: node, callee: callee, args: args, kind: callee.valueType.returnType)
|
||||
|
||||
|
||||
proc newTypedBlockStmt*(node: BlockStmt, body: seq[TypedNode]): TypedBlockStmt =
|
||||
## Initializes a new typed block statement
|
||||
result = TypedBlockStmt(node: node, body: body)
|
||||
|
||||
|
||||
proc newTypedWhileStmt*(node: WhileStmt, body: TypedBlockStmt, condition: TypedExpr): TypedWhileStmt =
|
||||
## Initializes a new typed while statement
|
||||
result = TypedWhileStmt(node: node, body: body, condition: condition)
|
||||
|
||||
|
||||
proc newTypedIfStmt*(node: IfStmt, thenBranch, elseBranch: TypedBlockStmt, condition: TypedExpr): TypedIfStmt =
|
||||
## Initializes a new typed block statement
|
||||
result = TypedIfStmt(node: node, thenBranch: thenBranch,
|
||||
elseBranch: elseBranch, condition: condition)
|
||||
|
||||
|
||||
proc getName*(self: TypedNode): Name =
|
||||
## Gets the name object associated with the
|
||||
## given typed node, if it has any
|
||||
case self.node.kind:
|
||||
of identExpr:
|
||||
result = TypedIdentExpr(self).name
|
||||
of NodeKind.funDecl, NodeKind.varDecl, NodeKind.typeDecl:
|
||||
result = TypedDecl(self).name
|
||||
else:
|
||||
result = nil # TODO
|
Loading…
Reference in New Issue