core: add compiler redeclaration check, tweak error formatting
This commit is contained in:
parent
18d64656a2
commit
b73af5f92f
1 changed files with 23 additions and 5 deletions
|
|
@ -58,7 +58,7 @@ func (e CompilerError) Format() string {
|
||||||
|
|
||||||
if src[i] == '\n' {
|
if src[i] == '\n' {
|
||||||
line++
|
line++
|
||||||
lineStart = int(i)
|
lineStart = int(i) + 1
|
||||||
pos = 0
|
pos = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -67,10 +67,12 @@ func (e CompilerError) Format() string {
|
||||||
b.WriteString("\n")
|
b.WriteString("\n")
|
||||||
lineEnd = lineStart
|
lineEnd = lineStart
|
||||||
for lineEnd < len(src) {
|
for lineEnd < len(src) {
|
||||||
lineEnd++
|
|
||||||
if src[lineEnd] == '\n' {
|
if src[lineEnd] == '\n' {
|
||||||
|
lineEnd++
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lineEnd++
|
||||||
}
|
}
|
||||||
|
|
||||||
begin := max(0, int(start)-lineStart)
|
begin := max(0, int(start)-lineStart)
|
||||||
|
|
@ -85,7 +87,7 @@ func (e CompilerError) Format() string {
|
||||||
b.WriteString(lineDescriptor)
|
b.WriteString(lineDescriptor)
|
||||||
b.WriteString(" | ")
|
b.WriteString(" | ")
|
||||||
|
|
||||||
b.WriteString(string(src[lineStart+1 : lineEnd]))
|
b.WriteString(string(src[lineStart : lineEnd-1]))
|
||||||
b.WriteString("\n")
|
b.WriteString("\n")
|
||||||
|
|
||||||
b.WriteString(strings.Repeat(" ", len(lineDescriptor)))
|
b.WriteString(strings.Repeat(" ", len(lineDescriptor)))
|
||||||
|
|
@ -326,6 +328,10 @@ func (c *Compiler) Compile(tree Node) error {
|
||||||
}
|
}
|
||||||
c.add(InstructionPop)
|
c.add(InstructionPop)
|
||||||
} else {
|
} else {
|
||||||
|
if c.isVarDeclaredHere(n.name) {
|
||||||
|
return c.error(fmt.Sprintf("%s is already declared in this scope", n.name), n)
|
||||||
|
}
|
||||||
|
|
||||||
err := c.setVar(n.name, n.value, n.declare)
|
err := c.setVar(n.name, n.value, n.declare)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -769,7 +775,7 @@ func (c *Compiler) affirmReturnSignature(tree Node, sig TypeSignature) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sig.Matches(v) {
|
if !sig.Matches(v) {
|
||||||
return c.error(fmt.Sprintf("function cannot return a value with type %s. must be %s", v, sig), n.value)
|
return c.error(fmt.Sprintf("function cannot return a value with type %s. defined to be %s", v, sig), n.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
case ConditionalNodeType:
|
case ConditionalNodeType:
|
||||||
|
|
@ -824,6 +830,18 @@ func (c *Compiler) affirmReturnSignature(tree Node, sig TypeSignature) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isVarDeclaredHere check whether a variable is declared in the current scope
|
||||||
|
func (c *Compiler) isVarDeclaredHere(name string) bool {
|
||||||
|
for i := c.stack.Current - 1; i >= 0 && c.stack.items[i].scope == int(c.scope); i-- {
|
||||||
|
v := c.stack.items[i]
|
||||||
|
if v.name == name {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Compiler) getVar(name string) {
|
func (c *Compiler) getVar(name string) {
|
||||||
if c.isGlobal(name) {
|
if c.isGlobal(name) {
|
||||||
c.add(InstructionGetGlobal)
|
c.add(InstructionGetGlobal)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue