Skip to content

Commit

Permalink
ivy: simplify (and correct) code for opdelete
Browse files Browse the repository at this point in the history
Was missing a check for EOF. Also, I didn't trust where it was
being done: too much state already built. None of it is needed.

Also add execution failure tests for bad opdeletes.
  • Loading branch information
robpike committed Aug 11, 2023
1 parent c7523a4 commit b7ce998
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 19 deletions.
21 changes: 9 additions & 12 deletions exec/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,28 +233,25 @@ func (c *Context) Define(fn *Function) {
c.Defs = append(c.Defs, OpDef{fn.Name, fn.IsBinary})
}

func (c *Context) UnDefine(fn *Function) {
binary := false
ary := "unary"
if fn.IsBinary {
binary = true
ary = "binary"
}
func (c *Context) Undefine(name string, binary bool) {
// Is it already defined?
for i, def := range c.Defs {
if def.Name == fn.Name && def.IsBinary == fn.IsBinary {
if def.Name == name && def.IsBinary == binary {
// Yes. Drop it.
c.Defs = append(c.Defs[:i], c.Defs[i+1:]...)
if binary {
delete(c.BinaryFn, fn.Name)
delete(c.BinaryFn, name)
} else {
delete(c.UnaryFn, fn.Name)
delete(c.UnaryFn, name)
}
return
}
}

value.Errorf("no definition for %s %s", ary, fn.Name)
ary := "unary"
if binary {
ary = "binary"
}
value.Errorf("no definition for %s %s", ary, name)
}

// noVar guarantees that there is no global variable with that name,
Expand Down
14 changes: 7 additions & 7 deletions parse/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ func (p *Parser) functionDefn() {
if p.peek().Type == scan.Identifier {
idents = append(idents, p.next().Text)
}
tok := p.next()
// Undefine if so requested.
if undefine {
p.need(scan.EOF)
p.context.Undefine(idents[len(idents)-2], len(idents) == 3)
return
}
// Install the function in the symbol table so recursive ops work. (As if.)
var installMap map[string]*exec.Function
if len(idents) == 3 {
Expand All @@ -65,12 +70,6 @@ func (p *Parser) functionDefn() {
if fn.Name == fn.Left || fn.Name == fn.Right {
p.errorf("argument name %q is function name", fn.Name)
}
// Undefine if so requested.
if undefine {
p.context.UnDefine(fn)
p.need(scan.EOF)
return
}
// Define it, but prepare to undefine if there's trouble.
prevDefn := installMap[fn.Name]
p.context.Define(fn)
Expand All @@ -86,6 +85,7 @@ func (p *Parser) functionDefn() {
}
}()

tok := p.next()
switch tok.Type {
case scan.Assign:
// Either one line:
Expand Down
6 changes: 6 additions & 0 deletions testdata/exec_fail.ivy
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,9 @@ op inc b =

inc 1
X

# no definition for unary foo
opdelete foo

# no definition for binary foo
opdelete x foo y

0 comments on commit b7ce998

Please sign in to comment.