parsing, lexing, some compiling of const
All checks were successful
/ test (push) Successful in 1m1s

This commit is contained in:
Neemek 2025-11-06 23:23:39 +01:00
parent beaa325c7b
commit f54d8304fc
5 changed files with 91 additions and 10 deletions

View file

@ -33,6 +33,7 @@ type ImportsResolver interface {
type LocalVariable struct {
name string
signature TypeSignature
value Value
scope int
}
@ -415,6 +416,25 @@ func (c *Compiler) compile(tree Node) error {
}
}
case ConstNodeType:
n := tree.(*ConstNode)
if !c.isTreeConstant(n.value) {
return c.error(fmt.Sprintf("value of %s is not constant", n.name), n.value)
}
value, err := c.compute(n.value)
if err != nil {
return err
}
t, err := c.deduceSignature(n)
if err != nil {
return err
}
c.registerConst(n.name, t, value)
case CallNodeType:
n := tree.(*CallNode)
@ -1023,6 +1043,16 @@ func (c *Compiler) registerVar(name string, t TypeSignature) {
c.stack.Push(LocalVariable{
name,
t,
nil,
int(c.scope),
})
}
func (c *Compiler) registerConst(name string, t TypeSignature, constant Value) {
c.stack.Push(LocalVariable{
name,
t,
constant,
int(c.scope),
})
}

View file

@ -50,6 +50,7 @@ const (
TokenVar
TokenIf
TokenElse
TokenConst
TokenImport
TokenComma
@ -349,6 +350,8 @@ func (l *Lexer) NextToken() (Token, error) {
return l.makeToken(TokenReturn), nil
case "import":
return l.makeToken(TokenImport), nil
case "const":
return l.makeToken(TokenConst), nil
default:
return l.makeToken(TokenName), nil
}

View file

@ -32,6 +32,7 @@ const (
ConditionalNodeType
LoopNodeType
AssignNodeType
ConstNodeType
CallNodeType
FunctionNodeType
ReturnNodeType
@ -75,6 +76,8 @@ func (n NodeType) String() string {
return "Breakpoint"
case UnaryNodeType:
return "Unary"
case ConstNodeType:
return "Const"
}
return "Invalid Node Type"
}
@ -476,6 +479,26 @@ func (n AssignNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
type ConstNode struct {
name string
value Node
start Pos
end Pos
}
func (n ConstNode) Type() NodeType {
return ConstNodeType
}
func (n ConstNode) String() string {
return fmt.Sprintf("define const %s to be %s", n.name, n.value)
}
func (n ConstNode) Bounds() (Pos, Pos) {
return n.start, n.end
}
// CallNode function call
type CallNode struct {
source Node

View file

@ -816,6 +816,31 @@ func (p *Parser) statement() (Node, error) {
defer p.advance()
return nil, p.error("import statements must be top-level", p.curr)
case TokenConst:
p.advance()
start := p.prev.Start
if err := p.expect(TokenName, "a const must be referred to by a name"); err != nil {
return nil, err
}
name := p.prev.Lexeme
if err := p.expect(TokenAssign, "const values must have an assigned value"); err != nil {
return nil, err
}
value, err := p.condition()
if err != nil {
return nil, err
}
return &ConstNode{
name,
value,
start,
p.prev.Start + p.prev.Length,
}, nil
default:
defer p.advance()
return nil, p.error("invalid statement", p.curr)