begin variable resolution

This commit is contained in:
Robin Bärtschi 2025-02-21 16:46:54 +01:00
parent 5664794c2f
commit ee26d1371c
3 changed files with 95 additions and 2 deletions

View File

@ -191,7 +191,6 @@ func (ie *IfExpression) String() string {
return builder.String()
}
// This is still a expression, because making it some other type of node would be to much work
type VariableDeclaration struct {
Token token.Token // The Identifier token
InitializingExpression Expression

View File

@ -170,7 +170,6 @@ func (ie *IfExpression) String() string {
return builder.String()
}
// This is still a expression, because making it some other type of node would be to much work
type VariableDeclaration struct {
Token token.Token // The Identifier token
InitializingExpression Expression
@ -197,7 +196,23 @@ func (vr *VariableReference) expressionNode() {}
func (vr *VariableReference) Type() types.Type {
return vr.VariableType
}
func (vr *VariableReference) TokenLiteral() string { return vr.Token.Literal }
func (vr *VariableReference) String() string {
return fmt.Sprintf("%s", vr.Identifier)
}
type AssignmentExpression struct {
Token token.Token // The Equal
Lhs Expression
Rhs Expression
}
func (ae *AssignmentExpression) expressionNode() {}
func (ae *AssignmentExpression) Type() types.Type {
return types.Unit
}
func (ae *AssignmentExpression) TokenLiteral() string { return ae.Token.Literal }
func (ae *AssignmentExpression) String() string {
return fmt.Sprintf("%s = %s", ae.Lhs.String(), ae.Rhs.String())
}

View File

@ -1 +1,80 @@
package typechecker
import (
"fmt"
"robaertschi.xyz/robaertschi/tt/ast"
"robaertschi.xyz/robaertschi/tt/types"
)
type Variable struct {
Name string
Type types.Type
}
type Scope struct {
Variables map[string]Variable
ParentScope *Scope
}
func (s *Scope) Get(name string) (Variable, bool) {
v, ok := s.Variables[name]
if ok {
return v, true
}
if s.ParentScope != nil {
return s.ParentScope.Get(name)
}
return Variable{}, false
}
func (s *Scope) Set(name string, t types.Type) {
s.Variables[name] = Variable{Name: name, Type: t}
}
func (s *Scope) Has(name string) bool {
_, ok := s.Variables[name]
if !ok && s.ParentScope != nil {
return s.ParentScope.Has(name)
}
return ok
}
func VarResolve(p *ast.Program) (Scope, error) {
s := Scope{Variables: make(map[string]Variable)}
for _, d := range p.Declarations {
switch d := d.(type) {
case *ast.FunctionDeclaration:
err := VarResolveExpr(&s, d.Body)
if err != nil {
return s, err
}
}
}
return s, nil
}
func VarResolveExpr(s *Scope, e ast.Expression) error {
switch e := e.(type) {
case *ast.ErrorExpression:
case *ast.AssignmentExpression:
case *ast.BinaryExpression:
case *ast.BlockExpression:
case *ast.BooleanExpression:
case *ast.IfExpression:
case *ast.IntegerExpression:
case *ast.VariableDeclaration:
case *ast.VariableReference:
default:
panic(fmt.Sprintf("unexpected ast.Expression: %#v", e))
}
return nil
}