mirror of
https://github.com/kanaka/mal.git
synced 2024-09-21 02:27:10 +03:00
Go: Fix panic on call to function with wrong number of arguments
This commit is contained in:
parent
810ec74a67
commit
07bd1c1ff1
@ -446,28 +446,52 @@ func swap_BANG(a []MalType) (MalType, error) {
|
||||
// core namespace
|
||||
var NS = map[string]MalType{
|
||||
"=": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return Equal_Q(a[0], a[1]), nil
|
||||
},
|
||||
"throw": throw,
|
||||
"nil?": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return Nil_Q(a[0]), nil
|
||||
},
|
||||
"true?": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return True_Q(a[0]), nil
|
||||
},
|
||||
"false?": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return False_Q(a[0]), nil
|
||||
},
|
||||
"symbol": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return Symbol{a[0].(string)}, nil
|
||||
},
|
||||
"symbol?": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return Symbol_Q(a[0]), nil
|
||||
},
|
||||
"string?": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return (String_Q(a[0]) && !Keyword_Q(a[0])), nil
|
||||
},
|
||||
"keyword": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
if Keyword_Q(a[0]) {
|
||||
return a[0], nil
|
||||
} else {
|
||||
@ -475,13 +499,22 @@ var NS = map[string]MalType{
|
||||
}
|
||||
},
|
||||
"keyword?": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return Keyword_Q(a[0]), nil
|
||||
},
|
||||
"number?": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return Number_Q(a[0]), nil
|
||||
},
|
||||
"fn?": fn_q,
|
||||
"macro?": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return MalFunc_Q(a[0]) && a[0].(MalFunc).GetMacro(), nil
|
||||
},
|
||||
|
||||
@ -490,35 +523,65 @@ var NS = map[string]MalType{
|
||||
"prn": func(a []MalType) (MalType, error) { return prn(a) },
|
||||
"println": func(a []MalType) (MalType, error) { return println(a) },
|
||||
"read-string": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return reader.Read_str(a[0].(string))
|
||||
},
|
||||
"slurp": slurp,
|
||||
"readline": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return readline.Readline(a[0].(string))
|
||||
},
|
||||
|
||||
"<": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) < a[1].(int), nil
|
||||
},
|
||||
"<=": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) <= a[1].(int), nil
|
||||
},
|
||||
">": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) > a[1].(int), nil
|
||||
},
|
||||
">=": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) >= a[1].(int), nil
|
||||
},
|
||||
"+": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) + a[1].(int), nil
|
||||
},
|
||||
"-": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) - a[1].(int), nil
|
||||
},
|
||||
"*": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) * a[1].(int), nil
|
||||
},
|
||||
"/": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) / a[1].(int), nil
|
||||
},
|
||||
"time-ms": time_ms,
|
||||
@ -527,30 +590,45 @@ var NS = map[string]MalType{
|
||||
return List{a, nil}, nil
|
||||
},
|
||||
"list?": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return List_Q(a[0]), nil
|
||||
},
|
||||
"vector": func(a []MalType) (MalType, error) {
|
||||
return Vector{a, nil}, nil
|
||||
},
|
||||
"vector?": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return Vector_Q(a[0]), nil
|
||||
},
|
||||
"hash-map": func(a []MalType) (MalType, error) {
|
||||
return NewHashMap(List{a, nil})
|
||||
},
|
||||
"map?": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return HashMap_Q(a[0]), nil
|
||||
},
|
||||
"assoc": assoc,
|
||||
"dissoc": dissoc,
|
||||
"get": get,
|
||||
"contains?": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return contains_Q(a[0], a[1])
|
||||
},
|
||||
"keys": keys,
|
||||
"vals": vals,
|
||||
|
||||
"sequential?": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return Sequential_Q(a[0]), nil
|
||||
},
|
||||
"cons": cons,
|
||||
@ -568,12 +646,25 @@ var NS = map[string]MalType{
|
||||
"with-meta": with_meta,
|
||||
"meta": meta,
|
||||
"atom": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return &Atom{a[0], nil}, nil
|
||||
},
|
||||
"atom?": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 1); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return Atom_Q(a[0]), nil
|
||||
},
|
||||
"deref": deref,
|
||||
"reset!": reset_BANG,
|
||||
"swap!": swap_BANG,
|
||||
}
|
||||
|
||||
func assertArgNum(a []MalType, n int) error {
|
||||
if len(a) != n {
|
||||
return errors.New("wrong number of arguments")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -102,19 +102,38 @@ func PRINT(exp MalType) (string, error) {
|
||||
|
||||
var repl_env = map[string]MalType{
|
||||
"+": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) + a[1].(int), nil
|
||||
},
|
||||
"-": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) - a[1].(int), nil
|
||||
},
|
||||
"*": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) * a[1].(int), nil
|
||||
},
|
||||
"/": func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) / a[1].(int), nil
|
||||
},
|
||||
}
|
||||
|
||||
func assertArgNum(a []MalType, n int) error {
|
||||
if len(a) != n {
|
||||
return errors.New("wrong number of arguments")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// repl
|
||||
func rep(str string) (MalType, error) {
|
||||
var exp MalType
|
||||
|
@ -164,15 +164,27 @@ func rep(str string) (MalType, error) {
|
||||
|
||||
func main() {
|
||||
repl_env.Set(Symbol{"+"}, func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) + a[1].(int), nil
|
||||
})
|
||||
repl_env.Set(Symbol{"-"}, func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) - a[1].(int), nil
|
||||
})
|
||||
repl_env.Set(Symbol{"*"}, func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) * a[1].(int), nil
|
||||
})
|
||||
repl_env.Set(Symbol{"/"}, func(a []MalType) (MalType, error) {
|
||||
if e := assertArgNum(a, 2); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return a[0].(int) / a[1].(int), nil
|
||||
})
|
||||
|
||||
@ -195,3 +207,10 @@ func main() {
|
||||
fmt.Printf("%v\n", out)
|
||||
}
|
||||
}
|
||||
|
||||
func assertArgNum(a []MalType, n int) error {
|
||||
if len(a) != n {
|
||||
return errors.New("wrong number of arguments")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
34
go/tests/step2_eval.mal
Normal file
34
go/tests/step2_eval.mal
Normal file
@ -0,0 +1,34 @@
|
||||
;; Testing evaluation of excessive arguments
|
||||
(+ 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(+ 1 2)
|
||||
;=>3
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+ 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of excessive arguments
|
||||
(- 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(- 1 2)
|
||||
;=>-1
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(- 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(-)
|
||||
;=>Error: wrong number of arguments
|
||||
|
34
go/tests/step3_env.mal
Normal file
34
go/tests/step3_env.mal
Normal file
@ -0,0 +1,34 @@
|
||||
;; Testing evaluation of excessive arguments
|
||||
(+ 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(+ 1 2)
|
||||
;=>3
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+ 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of excessive arguments
|
||||
(- 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(- 1 2)
|
||||
;=>-1
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(- 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(-)
|
||||
;=>Error: wrong number of arguments
|
||||
|
34
go/tests/step4_if_fn_do.mal
Normal file
34
go/tests/step4_if_fn_do.mal
Normal file
@ -0,0 +1,34 @@
|
||||
;; Testing evaluation of excessive arguments
|
||||
(+ 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(+ 1 2)
|
||||
;=>3
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+ 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of excessive arguments
|
||||
(= 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(= 1 2)
|
||||
;=>false
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(= 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(=)
|
||||
;=>Error: wrong number of arguments
|
||||
|
@ -1,2 +1,37 @@
|
||||
;; Go: skipping non-TCO recursion
|
||||
;; Reason: completes even at 100,000
|
||||
|
||||
;; Testing evaluation of excessive arguments
|
||||
(+ 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(+ 1 2)
|
||||
;=>3
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+ 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of excessive arguments
|
||||
(= 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(= 1 2)
|
||||
;=>false
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(= 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(=)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
|
34
go/tests/step6_file.mal
Normal file
34
go/tests/step6_file.mal
Normal file
@ -0,0 +1,34 @@
|
||||
;; Testing evaluation of excessive arguments
|
||||
(+ 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(+ 1 2)
|
||||
;=>3
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+ 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of excessive arguments
|
||||
(= 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(= 1 2)
|
||||
;=>false
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(= 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(=)
|
||||
;=>Error: wrong number of arguments
|
||||
|
34
go/tests/step7_quote.mal
Normal file
34
go/tests/step7_quote.mal
Normal file
@ -0,0 +1,34 @@
|
||||
;; Testing evaluation of excessive arguments
|
||||
(+ 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(+ 1 2)
|
||||
;=>3
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+ 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of excessive arguments
|
||||
(= 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(= 1 2)
|
||||
;=>false
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(= 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(=)
|
||||
;=>Error: wrong number of arguments
|
||||
|
34
go/tests/step8_macros.mal
Normal file
34
go/tests/step8_macros.mal
Normal file
@ -0,0 +1,34 @@
|
||||
;; Testing evaluation of excessive arguments
|
||||
(+ 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(+ 1 2)
|
||||
;=>3
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+ 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of excessive arguments
|
||||
(= 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(= 1 2)
|
||||
;=>false
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(= 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(=)
|
||||
;=>Error: wrong number of arguments
|
||||
|
34
go/tests/step9_try.mal
Normal file
34
go/tests/step9_try.mal
Normal file
@ -0,0 +1,34 @@
|
||||
;; Testing evaluation of excessive arguments
|
||||
(+ 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(+ 1 2)
|
||||
;=>3
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+ 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of excessive arguments
|
||||
(= 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(= 1 2)
|
||||
;=>false
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(= 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(=)
|
||||
;=>Error: wrong number of arguments
|
||||
|
34
go/tests/stepA_mal.mal
Normal file
34
go/tests/stepA_mal.mal
Normal file
@ -0,0 +1,34 @@
|
||||
;; Testing evaluation of excessive arguments
|
||||
(+ 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(+ 1 2)
|
||||
;=>3
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+ 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(+)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of excessive arguments
|
||||
(= 1 2 3)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Valid call
|
||||
(= 1 2)
|
||||
;=>false
|
||||
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(= 1)
|
||||
;=>Error: wrong number of arguments
|
||||
|
||||
;; Testing evaluation of missing arguments
|
||||
(=)
|
||||
;=>Error: wrong number of arguments
|
||||
|
Loading…
Reference in New Issue
Block a user