package parser
import (
"github.com/marzeq/qk/shared"
"github.com/marzeq/qk/symbols"
"github.com/marzeq/qk/tokeniser"
"github.com/marzeq/qk/types"
)
type (
Node interface{ GetLoc() shared.Location }
ExpressionNode interface {
Node
SetType(types.Type)
GetType() types.Type
}
)
type RootNode struct {
Body []Node
Loc shared.Location
}
func (n RootNode) GetLoc() shared.Location { return n.Loc }
type IdentifierNode struct {
Name string
Loc shared.Location
Symbol *symbols.Symbol
}
func (n IdentifierNode) GetLoc() shared.Location { return n.Loc }
func (n IdentifierNode) String() string { return n.Name }
func (n *IdentifierNode) SetType(t types.Type) {}
func (n *IdentifierNode) GetType() types.Type {
if n.Symbol == nil {
panic("identifier node has no symbol")
}
return n.Symbol.Type
}
type ModuleAccessNode struct {
ModName string
Ident *IdentifierNode
Loc shared.Location
Symbol *symbols.Symbol
Type types.Type
}
func (n ModuleAccessNode) GetLoc() shared.Location { return n.Loc }
func (n ModuleAccessNode) String() string {
if n.ModName == "" {
return n.Ident.String()
}
return n.ModName + ":" + n.Ident.String()
}
func (n *ModuleAccessNode) SetType(t types.Type) { n.Type = t }
func (n *ModuleAccessNode) GetType() types.Type { return n.Type }
type NamedTypeNode struct {
ModName string
Name string
Loc shared.Location
}
func (n NamedTypeNode) GetLoc() shared.Location { return n.Loc }
func (n NamedTypeNode) _type() {}
type StructField struct {
Name string
Type TypeNode
}
type StructTypeNode struct {
Fields []StructField
Loc shared.Location
}
func (n StructTypeNode) GetLoc() shared.Location { return n.Loc }
func (n StructTypeNode) _type() {}
type ArrayTypeNode struct {
ElementType TypeNode
Size int
Loc shared.Location
}
func (n ArrayTypeNode) GetLoc() shared.Location { return n.Loc }
func (n ArrayTypeNode) _type() {}
type PointerTypeNode struct {
BaseType TypeNode
Loc shared.Location
}
func (n PointerTypeNode) GetLoc() shared.Location { return n.Loc }
func (n PointerTypeNode) _type() {}
type TypeNode interface {
Node
_type() // marker method
}
type BoolLiteralNode struct {
Value string
Loc shared.Location
Type types.Type
}
func (n BoolLiteralNode) GetLoc() shared.Location { return n.Loc }
func (n *BoolLiteralNode) SetType(t types.Type) { n.Type = t }
func (n *BoolLiteralNode) GetType() types.Type { return n.Type }
type IntegerLiteralNode struct {
Value string
Loc shared.Location
Type types.Type
}
func (n IntegerLiteralNode) GetLoc() shared.Location { return n.Loc }
func (n *IntegerLiteralNode) SetType(t types.Type) { n.Type = t }
func (n *IntegerLiteralNode) GetType() types.Type { return n.Type }
type FloatLiteralNode struct {
Value string
Loc shared.Location
Type types.Type
}
func (n FloatLiteralNode) GetLoc() shared.Location { return n.Loc }
func (n *FloatLiteralNode) SetType(t types.Type) { n.Type = t }
func (n *FloatLiteralNode) GetType() types.Type { return n.Type }
type StringLiteralNode struct {
Value string
Loc shared.Location
Type types.Type
}
func (n StringLiteralNode) GetLoc() shared.Location { return n.Loc }
func (n *StringLiteralNode) SetType(t types.Type) { n.Type = t }
func (n *StringLiteralNode) GetType() types.Type { return n.Type }
type CharLiteralNode struct {
Value byte
Loc shared.Location
Type types.Type
}
func (n CharLiteralNode) GetLoc() shared.Location { return n.Loc }
func (n *CharLiteralNode) SetType(t types.Type) { n.Type = t }
func (n *CharLiteralNode) GetType() types.Type { return n.Type }
type NilLiteralNode struct {
Loc shared.Location
Type types.Type
}
func (n NilLiteralNode) GetLoc() shared.Location { return n.Loc }
func (n *NilLiteralNode) SetType(t types.Type) { n.Type = t }
func (n *NilLiteralNode) GetType() types.Type { return n.Type }
type StructLiteralNode struct {
Name *ModuleAccessNode
Fields []shared.Pair[string, ExpressionNode] // field name, value
Loc shared.Location
Symbol *symbols.Symbol
Type types.Type
}
func (n StructLiteralNode) GetLoc() shared.Location { return n.Loc }
func (n *StructLiteralNode) SetType(t types.Type) { n.Type = t }
func (n *StructLiteralNode) GetType() types.Type { return n.Type }
type ArrayLiteralNode struct {
Elements []ExpressionNode
Loc shared.Location
Type types.Type
}
func (n ArrayLiteralNode) GetLoc() shared.Location { return n.Loc }
func (n *ArrayLiteralNode) SetType(t types.Type) { n.Type = t }
func (n *ArrayLiteralNode) GetType() types.Type { return n.Type }
type FunctionCallNode struct {
Name *ModuleAccessNode
Args []ExpressionNode
Loc shared.Location
Symbol *symbols.Symbol
}
func (n FunctionCallNode) GetLoc() shared.Location { return n.Loc }
func (n *FunctionCallNode) SetType(t types.Type) {}
func (n *FunctionCallNode) GetType() types.Type {
if n.Symbol == nil || n.Symbol.Kind != symbols.SymbolKindFunction ||
n.Symbol.Signature == nil {
panic("invalid function call node")
}
if n.Symbol.Signature.ReturnType == nil {
return types.PrimitiveVoid
}
return n.Symbol.Signature.ReturnType
}
type IfExprBranch struct {
Condition ExpressionNode
Node ExpressionNode
}
type IfExprNode struct {
IfBranch IfExprBranch
ElseIfBranches []IfExprBranch
ElseBranch ExpressionNode
Loc shared.Location
Type types.Type
}
func (n IfExprNode) GetLoc() shared.Location { return n.Loc }
func (n *IfExprNode) SetType(t types.Type) { n.Type = t }
func (n *IfExprNode) GetType() types.Type { return n.Type }
type GivenExprNode struct {
Block *BlockNode
FinalExpr ExpressionNode
Loc shared.Location
Type types.Type
}
func (n GivenExprNode) GetLoc() shared.Location { return n.Loc }
func (n *GivenExprNode) SetType(t types.Type) { n.Type = t }
func (n *GivenExprNode) GetType() types.Type { return n.Type }
type UnaryOpKind uint
const (
UnaryOpLogicalNot UnaryOpKind = iota
UnaryOpNegate
UnaryOpReference
UnaryOpDereference
UnaryOpArrayLen
)
func (u UnaryOpKind) String() string {
switch u {
case UnaryOpLogicalNot:
return "not"
case UnaryOpNegate:
return "-"
case UnaryOpReference:
return "&"
case UnaryOpDereference:
return "*"
case UnaryOpArrayLen:
return "[]"
default:
return "unknown"
}
}
type UnaryOpNode struct {
Op UnaryOpKind
Operand ExpressionNode
Loc shared.Location
Type types.Type
}
func (n UnaryOpNode) GetLoc() shared.Location { return n.Loc }
func (n *UnaryOpNode) SetType(t types.Type) { n.Type = t }
func (n *UnaryOpNode) GetType() types.Type { return n.Type }
type IndexExprNode struct {
Subject ExpressionNode
Index ExpressionNode
Loc shared.Location
Type types.Type
}
func (n IndexExprNode) GetLoc() shared.Location { return n.Loc }
func (n *IndexExprNode) SetType(t types.Type) { n.Type = t }
func (n *IndexExprNode) GetType() types.Type { return n.Type }
type BinaryOpKind uint
const (
BinaryOpLogicalOr BinaryOpKind = iota
BinaryOpLogicalAnd
BinaryOpEqual
BinaryOpNotEqual
BinaryOpLess
BinaryOpLessEqual
BinaryOpGreater
BinaryOpGreaterEqual
BinaryOpAdd
BinaryOpSubtract
BinaryOpMultiply
BinaryOpDivide
BinaryOpModulo
)
type BinaryOpNode struct {
Op BinaryOpKind
Operand1 ExpressionNode
Operand2 ExpressionNode
Loc shared.Location
Type types.Type
}
func (n BinaryOpNode) GetLoc() shared.Location { return n.Loc }
func (n *BinaryOpNode) SetType(t types.Type) { n.Type = t }
func (n *BinaryOpNode) GetType() types.Type { return n.Type }
type CastNode struct {
ToType TypeNode
Operand ExpressionNode
Loc shared.Location
Type types.Type
}
func (n CastNode) GetLoc() shared.Location { return n.Loc }
func (n *CastNode) SetType(t types.Type) { n.Type = t }
func (n *CastNode) GetType() types.Type { return n.Type }
type SizeOfNode struct {
Operand TypeNode
Loc shared.Location
Type types.Type
}
func (n SizeOfNode) GetLoc() shared.Location { return n.Loc }
func (n *SizeOfNode) SetType(t types.Type) { n.Type = t }
func (n *SizeOfNode) GetType() types.Type { return n.Type }
type ImportNode struct {
Modules []string
Loc shared.Location
}
func (n ImportNode) GetLoc() shared.Location { return n.Loc }
type ModuleNode struct {
Name string
Loc shared.Location
}
func (n ModuleNode) GetLoc() shared.Location { return n.Loc }
type FunctionNodeType struct {
Name string
Type TypeNode
Mutable bool
}
type FunctionDefNode struct {
Name string
Args []FunctionNodeType
RetTypeNode TypeNode
Body Node
ExternFrom string
HasVariadic bool
Extern bool
Pub bool
Loc shared.Location
Symbol *symbols.Symbol
}
func (n FunctionDefNode) GetLoc() shared.Location { return n.Loc }
type TypeAliasNode struct {
Name string
Type TypeNode
Pub bool
Loc shared.Location
Symbol *symbols.Symbol
}
func (n TypeAliasNode) GetLoc() shared.Location { return n.Loc }
type IfBranch struct {
Condition ExpressionNode
Node *BlockNode
}
type IfNode struct {
IfBranch IfBranch
ElseIfBranches []IfBranch
ElseBranch *BlockNode
Loc shared.Location
}
func (n IfNode) GetLoc() shared.Location { return n.Loc }
type ForNode struct {
ExprsOrStmts []Node
Body *BlockNode
Loc shared.Location
}
func (n ForNode) GetLoc() shared.Location { return n.Loc }
type ControlKeywordNode struct {
Keyword tokeniser.KeywordKind
ReturnValue ExpressionNode // only for "return"
Loc shared.Location
}
func (n ControlKeywordNode) GetLoc() shared.Location { return n.Loc }
type DeclarationNode struct {
Name string
Mutable bool
Pub bool
TypeNode TypeNode
Value ExpressionNode
Loc shared.Location
Symbol *symbols.Symbol
}
func (n DeclarationNode) GetLoc() shared.Location { return n.Loc }
type AssignmentNode struct {
Assignee ExpressionNode
Value ExpressionNode
Loc shared.Location
}
func (n AssignmentNode) GetLoc() shared.Location { return n.Loc }
type ArrayAssignmentNode struct {
Assignee ExpressionNode
Index ExpressionNode
Value ExpressionNode
Loc shared.Location
}
func (n ArrayAssignmentNode) GetLoc() shared.Location { return n.Loc }
type BlockNode struct {
Body []Node
Loc shared.Location
}
func (n BlockNode) GetLoc() shared.Location { return n.Loc }