Added more tests
This commit is contained in:
parent
4faa1641c6
commit
2f7319e6a0
@ -20,12 +20,14 @@ func TestErrors(t *testing.T) {
|
|||||||
{"ExpectedFunctionParameters.q", errors.ExpectedFunctionParameters},
|
{"ExpectedFunctionParameters.q", errors.ExpectedFunctionParameters},
|
||||||
{"InvalidInstructionIdentifier.q", &errors.InvalidInstruction{Instruction: "abc"}},
|
{"InvalidInstructionIdentifier.q", &errors.InvalidInstruction{Instruction: "abc"}},
|
||||||
{"InvalidInstructionNumber.q", &errors.InvalidInstruction{Instruction: "123"}},
|
{"InvalidInstructionNumber.q", &errors.InvalidInstruction{Instruction: "123"}},
|
||||||
|
{"InvalidExpression.q", errors.InvalidExpression},
|
||||||
{"MissingAssignValue.q", errors.MissingAssignValue},
|
{"MissingAssignValue.q", errors.MissingAssignValue},
|
||||||
{"MissingBlockEnd.q", errors.MissingBlockEnd},
|
{"MissingBlockEnd.q", errors.MissingBlockEnd},
|
||||||
{"MissingBlockStart.q", errors.MissingBlockStart},
|
{"MissingBlockStart.q", errors.MissingBlockStart},
|
||||||
{"MissingGroupEnd.q", errors.MissingGroupEnd},
|
{"MissingGroupEnd.q", errors.MissingGroupEnd},
|
||||||
{"MissingGroupStart.q", errors.MissingGroupStart},
|
{"MissingGroupStart.q", errors.MissingGroupStart},
|
||||||
{"VariableAlreadyExists.q", &errors.VariableAlreadyExists{Name: "a"}},
|
{"VariableAlreadyExists.q", &errors.VariableAlreadyExists{Name: "a"}},
|
||||||
|
{"UnknownIdentifier.q", &errors.UnknownIdentifier{Name: "x"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
@ -156,29 +156,10 @@ func (f *Function) CompileFunctionCall(expr *expression.Expression) error {
|
|||||||
parameters := expr.Children[1:]
|
parameters := expr.Children[1:]
|
||||||
|
|
||||||
for i, parameter := range parameters {
|
for i, parameter := range parameters {
|
||||||
switch parameter.Token.Kind {
|
err := f.ExpressionToRegister(parameter, f.CPU.Syscall[i])
|
||||||
case token.Identifier:
|
|
||||||
name := parameter.Token.Text()
|
|
||||||
variable, exists := f.Variables[name]
|
|
||||||
|
|
||||||
if !exists {
|
if err != nil {
|
||||||
panic("Unknown identifier " + name)
|
return err
|
||||||
}
|
|
||||||
|
|
||||||
if !variable.IsConst {
|
|
||||||
panic("Not implemented yet")
|
|
||||||
}
|
|
||||||
|
|
||||||
n, _ := strconv.Atoi(variable.Value.Token.Text())
|
|
||||||
f.Assembler.MoveRegisterNumber(f.CPU.Syscall[i], uint64(n))
|
|
||||||
|
|
||||||
case token.Number:
|
|
||||||
value := parameter.Token.Text()
|
|
||||||
n, _ := strconv.Atoi(value)
|
|
||||||
f.Assembler.MoveRegisterNumber(f.CPU.Syscall[i], uint64(n))
|
|
||||||
|
|
||||||
default:
|
|
||||||
panic("Unknown expression")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,6 +172,59 @@ func (f *Function) CompileFunctionCall(expr *expression.Expression) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExpressionToRegister moves the result of an expression into the given register.
|
||||||
|
func (f *Function) ExpressionToRegister(root *expression.Expression, register cpu.Register) error {
|
||||||
|
if root.IsLeaf() {
|
||||||
|
return f.TokenToRegister(root.Token, register)
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.New(errors.NotImplemented, f.File, root.Token.Position)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TokenToRegister moves a token into a register.
|
||||||
|
// It only works with identifiers, numbers and strings.
|
||||||
|
func (f *Function) TokenToRegister(t token.Token, register cpu.Register) error {
|
||||||
|
switch t.Kind {
|
||||||
|
case token.Identifier:
|
||||||
|
name := t.Text()
|
||||||
|
variable, exists := f.Variables[name]
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
return errors.New(&errors.UnknownIdentifier{Name: name}, f.File, t.Position)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !variable.IsConst {
|
||||||
|
return errors.New(errors.NotImplemented, f.File, t.Position)
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err := strconv.Atoi(variable.Value.Token.Text())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
f.Assembler.MoveRegisterNumber(register, uint64(n))
|
||||||
|
return nil
|
||||||
|
|
||||||
|
case token.Number:
|
||||||
|
value := t.Text()
|
||||||
|
n, err := strconv.Atoi(value)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
f.Assembler.MoveRegisterNumber(register, uint64(n))
|
||||||
|
return nil
|
||||||
|
|
||||||
|
case token.String:
|
||||||
|
return errors.New(errors.NotImplemented, f.File, t.Position)
|
||||||
|
|
||||||
|
default:
|
||||||
|
return errors.New(errors.InvalidExpression, f.File, t.Position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// PrintAsm shows the assembly instructions.
|
// PrintAsm shows the assembly instructions.
|
||||||
func (f *Function) PrintAsm() {
|
func (f *Function) PrintAsm() {
|
||||||
ansi.Bold.Println(f.Name)
|
ansi.Bold.Println(f.Name)
|
||||||
|
@ -2,5 +2,7 @@ package errors
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
InvalidStatement = &Base{"Invalid statement"}
|
InvalidStatement = &Base{"Invalid statement"}
|
||||||
|
InvalidExpression = &Base{"Invalid expression"}
|
||||||
MissingAssignValue = &Base{"Missing assignment value"}
|
MissingAssignValue = &Base{"Missing assignment value"}
|
||||||
|
NotImplemented = &Base{"Not implemented"}
|
||||||
)
|
)
|
||||||
|
18
src/errors/UnknownIdentifier.go
Normal file
18
src/errors/UnknownIdentifier.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package errors
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// UnknownIdentifier represents unknown variables.
|
||||||
|
type UnknownIdentifier struct {
|
||||||
|
Name string
|
||||||
|
CorrectName string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error generates the string representation.
|
||||||
|
func (err *UnknownIdentifier) Error() string {
|
||||||
|
if err.CorrectName != "" {
|
||||||
|
return fmt.Sprintf("Unknown variable '%s', did you mean '%s'?", err.Name, err.CorrectName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("Unknown variable '%s'", err.Name)
|
||||||
|
}
|
3
tests/errors/InvalidExpression.q
Normal file
3
tests/errors/InvalidExpression.q
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
main() {
|
||||||
|
syscall(+, -, *, /)
|
||||||
|
}
|
3
tests/errors/UnknownIdentifier.q
Normal file
3
tests/errors/UnknownIdentifier.q
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
main() {
|
||||||
|
syscall(x)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user