mirror of
https://github.com/RoBaertschi/tt.git
synced 2025-04-16 05:53:30 +00:00
begin variable resolution
This commit is contained in:
parent
5664794c2f
commit
ee26d1371c
@ -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
|
||||
|
17
tast/tast.go
17
tast/tast.go
@ -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())
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user