static type analysis, formatted compiler errors, hex support, composite types, updated cli, more global builtins, fix list form, fix value refs

This commit is contained in:
Neemek 2025-03-18 20:22:46 +01:00
parent 84cc845748
commit 954308b29f
Signed by: neemek
GPG key ID: 28360A8951CD0E9B
18 changed files with 1352 additions and 285 deletions

View file

@ -11,6 +11,8 @@ type NodeType int
type Node interface {
Type() NodeType
String() string
Bounds() (Pos, Pos)
}
const (
@ -21,6 +23,7 @@ const (
NilNodeType
ListNodeType
BinaryNodeType
UnaryNodeType
BlockNodeType
ConditionalNodeType
LoopNodeType
@ -69,6 +72,8 @@ func (n NodeType) String() string {
return "Breakpoint"
case ImportNodeType:
return "Import"
case UnaryNodeType:
return "Unary"
}
return "Invalid Node Type"
}
@ -76,6 +81,9 @@ func (n NodeType) String() string {
// ReferenceNode a reference to a variable on the stack
type ReferenceNode struct {
name string
start Pos
end Pos
}
func (n ReferenceNode) Type() NodeType {
@ -86,10 +94,17 @@ func (n ReferenceNode) String() string {
return n.name
}
func (n ReferenceNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
// StringNode string/text values
type StringNode struct {
value string
quoted string
start Pos
end Pos
}
func (n StringNode) Type() NodeType {
@ -100,8 +115,15 @@ func (n StringNode) String() string {
return n.quoted
}
func (n StringNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
type NumberNode struct {
value float64
start Pos
end Pos
}
func (n NumberNode) Type() NodeType {
@ -112,9 +134,16 @@ func (n NumberNode) String() string {
return strconv.FormatFloat(n.value, 'g', -1, NumberSize)
}
func (n NumberNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
// ListNode a list or sequence of values (items)
type ListNode struct {
items []Node
start Pos
end Pos
}
func (n ListNode) Type() NodeType {
@ -125,18 +154,25 @@ func (n ListNode) String() string {
sb := strings.Builder{}
sb.WriteString("[")
for i, item := range n.items {
sb.WriteString(item.String())
if i > 0 {
sb.WriteString(", ")
}
sb.WriteString(item.String())
}
sb.WriteString("]")
return sb.String()
}
func (n ListNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
type AccessNode struct {
source Node
property string
start Pos
end Pos
}
func (n AccessNode) Type() NodeType {
@ -147,6 +183,10 @@ func (n AccessNode) String() string {
return fmt.Sprintf("(%s from %s)", n.property, n.source)
}
func (n AccessNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
type BinaryOperation uint
func (n BinaryOperation) String() string {
@ -198,11 +238,45 @@ const (
BinaryGreaterEqual
)
func (n BinaryOperation) Symbol() string {
switch n {
case BinaryAddition:
return "+"
case BinarySubtraction:
return "-"
case BinaryMultiplication:
return "*"
case BinaryDivision:
return "/"
case BinaryEquality:
return "=="
case BinaryInequality:
return "!="
case BinaryLess:
return "<"
case BinaryGreater:
return ">"
case BinaryAnd:
return "&&"
case BinaryOr:
return "||"
case BinaryLessEqual:
return "<="
case BinaryGreaterEqual:
return ">="
}
panic("unsupported binary operation to symbol conversion for " + n.String())
}
// BinaryNode All operations which take 2 variables
type BinaryNode struct {
BinaryOperation
Left Node
Right Node
start Pos
end Pos
}
func (n BinaryNode) Type() NodeType {
@ -213,9 +287,65 @@ func (n BinaryNode) String() string {
return fmt.Sprintf("%s %s %s", n.Left.String(), n.BinaryOperation.String(), n.Right.String())
}
func (n BinaryNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
type UnaryOperation int
const (
UnaryNegate UnaryOperation = iota
UnaryNot
)
func (op UnaryOperation) String() string {
switch op {
case UnaryNegate:
return "negate"
case UnaryNot:
return "not"
}
panic("unimplemented unary operation to string conversion")
}
func (op UnaryOperation) Symbol() string {
switch op {
case UnaryNegate:
return "-"
case UnaryNot:
return "!"
}
panic("unimplemented unary operation to symbol conversion")
}
type UnaryNode struct {
UnaryOperation
value Node
start Pos
end Pos
}
func (n UnaryNode) Type() NodeType {
return UnaryNodeType
}
func (n UnaryNode) String() string {
return fmt.Sprintf("%s %s", n.UnaryOperation.String(), n.value.String())
}
func (n UnaryNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
// BooleanNode boolean value
type BooleanNode struct {
value bool
start Pos
end Pos
}
func (n BooleanNode) Type() NodeType {
@ -226,8 +356,15 @@ func (n BooleanNode) String() string {
return strconv.FormatBool(n.value)
}
func (n BooleanNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
// NilNode nil value
type NilNode struct{}
type NilNode struct {
start Pos
end Pos
}
func (n NilNode) Type() NodeType {
return NilNodeType
@ -237,9 +374,16 @@ func (n NilNode) String() string {
return "nil"
}
func (n NilNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
// BlockNode block node with statements
type BlockNode struct {
statements []Node
start Pos
end Pos
}
func (n BlockNode) Type() NodeType {
@ -257,8 +401,15 @@ func (n BlockNode) String() string {
return builder.String()
}
func (n BlockNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
type ImportNode struct {
path string
start Pos
end Pos
}
func (n ImportNode) Type() NodeType {
@ -269,11 +420,18 @@ func (n ImportNode) String() string {
return fmt.Sprintf("import %s", n.path)
}
func (n ImportNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
// ConditionalNode conditionals (if statements)
type ConditionalNode struct {
condition Node
do Node
otherwise Node
start Pos
end Pos
}
func (n ConditionalNode) Type() NodeType {
@ -284,10 +442,17 @@ func (n ConditionalNode) String() string {
return fmt.Sprintf("if %s then %s otheriwise %s", n.condition.String(), n.do.String(), n.otherwise.String())
}
func (n ConditionalNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
// LoopNode Loops (for/while)
type LoopNode struct {
condition Node
do Node
start Pos
end Pos
}
func (n LoopNode) Type() NodeType {
@ -298,11 +463,18 @@ func (n LoopNode) String() string {
return fmt.Sprintf("while %s loop %s", n.condition.String(), n.do.String())
}
func (n LoopNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
// AssignNode assignment
type AssignNode struct {
name string
value Node
declare bool
start Pos
end Pos
}
func (n AssignNode) Type() NodeType {
@ -313,11 +485,18 @@ func (n AssignNode) String() string {
return fmt.Sprintf("set %s to %s", n.name, n.value)
}
func (n AssignNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
// CallNode function call
type CallNode struct {
source Node
args []Node
keep bool
start Pos
end Pos
}
func (n CallNode) Type() NodeType {
@ -328,17 +507,24 @@ func (n CallNode) String() string {
return fmt.Sprintf("call %s with args (%s)", n.source.String(), n.args)
}
func (n CallNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
// FunctionNode definition of function
type FunctionNode struct {
name string
parameters []FunctionParameter
yield TypeSignature
logic Node
start Pos
end Pos
}
type FunctionParameter struct {
name string
signature TypeSignature
Name string
Signature TypeSignature
}
func (n FunctionNode) Type() NodeType {
@ -349,9 +535,16 @@ func (n FunctionNode) String() string {
return fmt.Sprintf("definition of %s, do %s", n.name, n.logic.String())
}
func (n FunctionNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
// ReturnNode return a value out of this context
type ReturnNode struct {
value Node
start Pos
end Pos
}
func (n ReturnNode) Type() NodeType {
@ -362,7 +555,14 @@ func (n ReturnNode) String() string {
return fmt.Sprintf("return %s", n.value)
}
type BreakpointNode struct{}
func (n ReturnNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
type BreakpointNode struct {
start Pos
end Pos
}
func (n BreakpointNode) Type() NodeType {
return BreakpointNodeType
@ -371,3 +571,7 @@ func (n BreakpointNode) Type() NodeType {
func (n BreakpointNode) String() string {
return "breakpoint"
}
func (n BreakpointNode) Bounds() (Pos, Pos) {
return n.start, n.end
}