diff --git a/main_test.go b/errors_test.go similarity index 94% rename from main_test.go rename to errors_test.go index be2aa55..5512f08 100644 --- a/main_test.go +++ b/errors_test.go @@ -25,6 +25,7 @@ func TestErrors(t *testing.T) { {"MissingBlockStart.q", errors.MissingBlockStart}, {"MissingGroupEnd.q", errors.MissingGroupEnd}, {"MissingGroupStart.q", errors.MissingGroupStart}, + {"VariableAlreadyExists.q", &errors.VariableAlreadyExists{Name: "a"}}, } for _, test := range tests { diff --git a/src/build/Function.go b/src/build/Function.go index f303968..251d5e1 100644 --- a/src/build/Function.go +++ b/src/build/Function.go @@ -131,13 +131,21 @@ func (f *Function) CompileInstruction(line token.List) error { return errors.New(errors.MissingAssignValue, f.File, expr.LastChild().Token.After()) } - name := expr.Children[0] + name := expr.Children[0].Token.Text() + _, exists := f.Variables[name] + + if exists { + return errors.New(&errors.VariableAlreadyExists{Name: name}, f.File, expr.Children[0].Token.Position) + } + value := expr.Children[1] + // All expressions are returned to the memory pool. + // To avoid losing variable values, we will remove it from the expression. expr.RemoveChild(value) - f.Variables[name.Token.Text()] = &Variable{ - Name: name.Token.Text(), + f.Variables[name] = &Variable{ + Name: name, Value: value, IsConst: true, } diff --git a/src/errors/VariableAlreadyExists.go b/src/errors/VariableAlreadyExists.go new file mode 100644 index 0000000..4cad219 --- /dev/null +++ b/src/errors/VariableAlreadyExists.go @@ -0,0 +1,13 @@ +package errors + +import "fmt" + +// VariableAlreadyExists is used when existing variables are used for new variable declarations. +type VariableAlreadyExists struct { + Name string +} + +// Error generates the string representation. +func (err *VariableAlreadyExists) Error() string { + return fmt.Sprintf("Variable '%s' already exists", err.Name) +} diff --git a/tests/errors/VariableAlreadyExists.q b/tests/errors/VariableAlreadyExists.q new file mode 100644 index 0000000..e55bbe6 --- /dev/null +++ b/tests/errors/VariableAlreadyExists.q @@ -0,0 +1,4 @@ +main() { + a := 1 + a := 2 +} \ No newline at end of file