Added more tests

This commit is contained in:
2025-03-09 19:24:15 +01:00
parent 016938932f
commit 6c659a2b0c
8 changed files with 58 additions and 23 deletions

View File

@ -24,13 +24,13 @@ func (f *Function) CompileAssignDivision(expr *expression.Expression) error {
)
if expr.Token.Kind == token.Define {
quotientVariable, err = f.Define(variables.Children[0])
quotientVariable, err = f.NewVariable(variables.Children[0])
if err != nil {
return err
}
remainderVariable, err = f.Define(variables.Children[1])
remainderVariable, err = f.NewVariable(variables.Children[1])
if err != nil {
return err

View File

@ -13,7 +13,7 @@ func (f *Function) CompileDefinition(node *ast.Define) error {
right := node.Expression.Children[1]
if left.IsLeaf() {
variable, err := f.Define(left)
variable, err := f.NewVariable(left)
if err != nil {
return err

View File

@ -9,6 +9,7 @@ import (
"git.urbach.dev/cli/q/src/errors"
"git.urbach.dev/cli/q/src/eval"
"git.urbach.dev/cli/q/src/expression"
"git.urbach.dev/cli/q/src/scope"
"git.urbach.dev/cli/q/src/token"
"git.urbach.dev/cli/q/src/types"
)
@ -29,14 +30,15 @@ func (f *Function) CompileFor(loop *ast.For) error {
to *expression.Expression
)
counter = f.NewRegister()
defer f.FreeRegister(counter)
switch loop.Head.Token.Kind {
case token.Define:
from = loop.Head.Children[1].Children[0]
to = loop.Head.Children[1].Children[1]
case token.Range:
counter = f.NewRegister()
defer f.FreeRegister(counter)
from = loop.Head.Children[0]
to = loop.Head.Children[1]
@ -60,20 +62,6 @@ func (f *Function) CompileFor(loop *ast.For) error {
return errors.New(&errors.TypeMismatch{Encountered: value.Type().Name(), Expected: types.AnyInt.Name()}, f.File, to.Token.Position)
}
scope := f.PushScope(loop.Body, f.File.Bytes)
scope.InLoop = true
if loop.Head.Token.Kind == token.Define {
variable, err := f.Define(loop.Head.Children[0])
if err != nil {
return err
}
counter = variable.Value.Register
f.AddVariable(variable)
}
switch value := value.(type) {
case *eval.Number:
f.AddLabel(label)
@ -95,6 +83,29 @@ func (f *Function) CompileFor(loop *ast.For) error {
panic(fmt.Errorf("%s: not implemented: %v", f.UniqueName, value))
}
loopScope := f.PushScope(loop.Body, f.File.Bytes)
loopScope.InLoop = true
if loop.Head.Token.Kind == token.Define {
leaf := loop.Head.Children[0]
name := leaf.Token.Text(f.File.Bytes)
variable := f.VariableByName(name)
if variable != nil {
return errors.New(&errors.VariableAlreadyExists{Name: name}, f.File, leaf.Token.Position)
}
variable = &scope.Variable{
Name: name,
Value: eval.Register{
Register: counter,
Alive: ast.Count(loop.Body, f.File.Bytes, token.Identifier, name),
},
}
f.AddVariable(variable)
}
f.Jump(asm.JGE, labelEnd)
err = f.CompileAST(loop.Body)
f.RegisterNumber(asm.ADD, counter, 1)

View File

@ -15,7 +15,7 @@ func (f *Function) MultiDefine(left *expression.Expression, right *expression.Ex
}
return left.EachLeaf(func(leaf *expression.Expression) error {
variable, err := f.Define(leaf)
variable, err := f.NewVariable(leaf)
if err != nil {
return err

View File

@ -8,8 +8,8 @@ import (
"git.urbach.dev/cli/q/src/token"
)
// Define defines a new variable.
func (f *Function) Define(leaf *expression.Expression) (*scope.Variable, error) {
// NewVariable creates a new variable.
func (f *Function) NewVariable(leaf *expression.Expression) (*scope.Variable, error) {
name := leaf.Token.Text(f.File.Bytes)
variable := f.VariableByName(name)