123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869 |
- package attl
- func p(env *Environment, args ...Value) (Value, Effect) {
- for _, arg := range args {
- print(arg, " ")
- }
- print("\n")
- return nil, nil
- }
- func print_(env *Environment, args ...Value) (Value, Effect) {
- var msg string
- erra := Args(args, &msg)
- if erra != nil {
- return env.FailString("printf: ${1}", erra)
- }
- extra := []Value{}
- if len(args) > 1 {
- extra = args[1:len(args)]
- }
- n, err := env.Printi(msg, extra...)
- if err == nil {
- return Int(n), nil
- }
- return Int(n), ErrorFromError(err)
- }
- func write(env *Environment, args ...Value) (Value, Effect) {
- var msg string
- erra := Args(args, &msg)
- if erra != nil {
- return env.FailString("write: ${1}", erra)
- }
- n, err := env.Write(msg)
- if err == nil {
- return Int(n), nil
- }
- return Int(n), ErrorFromError(err)
- }
- func iadd(env *Environment, args ...Value) (Value, Effect) {
- var i, j int
- err := Args(args, &i, &j)
- if err != nil {
- return env.Fail(err)
- }
- return Int(i + j), nil
- }
- func isub(env *Environment, args ...Value) (Value, Effect) {
- var v1, v2 int
- err := Args(args, &v1, &v2)
- if err != nil {
- return env.Fail(err)
- }
- return Int(v1 - v2), nil
- }
- func imul(env *Environment, args ...Value) (Value, Effect) {
- var v1, v2 int
- err := Args(args, &v1, &v2)
- if err != nil {
- return env.Fail(err)
- }
- return Int(v1 * v2), nil
- }
- func idiv(env *Environment, args ...Value) (Value, Effect) {
- var v1, v2 int
- err := Args(args, &v1, &v2)
- if err != nil {
- return env.Fail(err)
- }
- if v2 == 0 {
- return nil, ErrorFromString("division by 0")
- }
- return Int(v1 / v2), nil
- }
- func igt(env *Environment, args ...Value) (Value, Effect) {
- var v1, v2 int
- err := Args(args, &v1, &v2)
- if err != nil {
- return env.Fail(err)
- }
- return Bool(v1 > v2), nil
- }
- func ilt(env *Environment, args ...Value) (Value, Effect) {
- var v1, v2 int
- err := Args(args, &v1, &v2)
- if err != nil {
- return env.Fail(err)
- }
- return Bool(v1 < v2), nil
- }
- func ige(env *Environment, args ...Value) (Value, Effect) {
- var v1, v2 int
- err := Args(args, &v1, &v2)
- if err != nil {
- return env.Fail(err)
- }
- return Bool(v1 >= v2), nil
- }
- func ile(env *Environment, args ...Value) (Value, Effect) {
- var v1, v2 int
- err := Args(args, &v1, &v2)
- if err != nil {
- return env.Fail(err)
- }
- return Bool(v1 <= v2), nil
- }
- func ieq(env *Environment, args ...Value) (Value, Effect) {
- var v1, v2 int
- err := Args(args, &v1, &v2)
- if err != nil {
- return env.Fail(err)
- }
- return Bool(v1 == v2), nil
- }
- func seq(env *Environment, args ...Value) (Value, Effect) {
- var v1, v2 string
- err := Args(args, &v1, &v2)
- if err != nil {
- return env.Fail(err)
- }
- return Bool(v1 == v2), nil
- }
- func teq(env *Environment, args ...Value) (Value, Effect) {
- var t1, t2 Type
- err := Args(args, &t1, &t2)
- if err != nil {
- return env.Fail(err)
- }
- return Bool(t1 == t2), nil
- }
- func updateIntByName(update func(in Int) Int, env *Environment, args ...Value) (Int, Effect) {
- var name Word
- err := Args(args, &name)
- if err != nil {
- return Int(0), err
- }
- val := env.Lookup(name.String())
- vi, ok := val.(Int)
- if !ok {
- return Int(0), ErrorFromString("Not an integer.")
- }
- newi := update(vi)
- env.Set(name.String(), newi)
- return newi, nil
- }
- func inc(env *Environment, args ...Value) (Value, Effect) {
- return updateIntByName(func(in Int) Int {
- return in + 1
- }, env, args...)
- }
- func dec(env *Environment, args ...Value) (Value, Effect) {
- return updateIntByName(func(in Int) Int {
- return in - 1
- }, env, args...)
- }
- func str(env *Environment, args ...Value) (Value, Effect) {
- var v1 Value
- err := Args(args, &v1)
- if err != nil {
- return env.Fail(err)
- }
- return String(v1.String()), nil
- }
- func int_(env *Environment, args ...Value) (Value, Effect) {
- var v1 Value
- err := Args(args, &v1)
- if err != nil {
- return env.Fail(err)
- }
- rs := []rune(v1.String() + " ")
- index := 0
- return ParseInteger(rs, &index)
- }
- func boolBinop(op func(b1, b2 bool) bool, env *Environment, args ...Value) (Value, Effect) {
- var v1, v2 bool
- err := Args(args, &v1, &v2)
- if err != nil {
- return env.Fail(err)
- }
- return Bool(op(v1, v2)), nil
- }
- func isnil(env *Environment, args ...Value) (Value, Effect) {
- if len(args) < 1 {
- return env.FailString("isnil requires 1 argument")
- }
- return Bool(args[0] == nil), nil
- }
- func band(env *Environment, args ...Value) (Value, Effect) {
- return boolBinop(func(b1, b2 bool) bool {
- return b1 && b2
- }, env, args...)
- }
- func bor(env *Environment, args ...Value) (Value, Effect) {
- return boolBinop(func(b1, b2 bool) bool {
- return b1 || b2
- }, env, args...)
- }
- func bxor(env *Environment, args ...Value) (Value, Effect) {
- return boolBinop(func(b1, b2 bool) bool {
- return b1 != b2
- }, env, args...)
- }
- func bnot(env *Environment, args ...Value) (Value, Effect) {
- var v1 bool
- err := Args(args, &v1)
- if err != nil {
- return env.Fail(err)
- }
- return Bool(!v1), nil
- }
- func val(env *Environment, args ...Value) (Value, Effect) {
- if len(args) < 1 {
- return env.FailString("val requres at least one argument.")
- }
- return List(args), nil
- }
- func ret(env *Environment, args ...Value) (Value, Effect) {
- if len(args) < 1 {
- return env.Return(nil)
- } else if len(args) == 1 {
- return env.Return(args[0])
- } else {
- return env.Return(List(args))
- }
- }
- func fail(env *Environment, args ...Value) (Value, Effect) {
- if len(args) < 1 {
- return env.Fail(ErrorFromString("fail"))
- } else {
- return env.FailString(args[0].String(), args[1:len(args)]...)
- }
- }
- func break_(env *Environment, args ...Value) (Value, Effect) {
- if len(args) < 1 {
- return env.Break(nil)
- } else if len(args) == 1 {
- return env.Break(args[0])
- } else {
- return env.Break(List(args))
- }
- }
- func nop(env *Environment, args ...Value) (Value, Effect) {
- return nil, nil
- }
- func typeof_(env *Environment, args ...Value) (Value, Effect) {
- var val Value
- err := Args(args, &val)
- if err != nil {
- return nil, err
- }
- return TypeOf(val), nil
- }
- func type_(env *Environment, args ...Value) (Value, Effect) {
- var val Value
- err := Args(args, &val)
- if err != nil {
- return nil, err
- }
- name := val.String()
- return Type(name), nil
- }
- func to(env *Environment, args ...Value) (Value, Effect) {
- var name string
- if len(args) < 2 {
- return env.FailString("to needs at least 2 arguments")
- }
- err := Convert(args[0], &name)
- if err != nil {
- return env.Fail(err)
- }
- block, ok := (args[len(args)-1]).(Block)
- if !ok {
- return env.FailString("to: last argument must be a block")
- }
- last := args[len(args)-1]
- block, isBlock := last.(Block)
- if !isBlock {
- return env.FailString("Not a block")
- }
- params := args[1 : len(args)-1]
- defined := Defined{name, params, block}
- env.Define(name, defined, 1)
- return defined, nil
- }
- func do(env *Environment, args ...Value) (Value, Effect) {
- var name string
- var doArgs List
- err := Args(args, &name, &doArgs)
- if err != nil {
- return env.Fail(err)
- }
- fun := env.Lookup(name)
- if fun == nil {
- return env.FailString("Cannot evaluate unknown order: " + name)
- }
- eva, ok := fun.(Evaler)
- if !ok {
- return env.FailString("Cannot evaluate: " + name)
- }
- return eva.Eval(env, doArgs...)
- }
- func if_(env *Environment, args ...Value) (Value, Effect) {
- var cond, ok, haveElse bool
- var ifBlock, elseBlock Block
- if len(args) < 2 {
- return env.FailString("if needs at least 2 arguments")
- }
- if len(args) > 4 {
- return env.FailString("if needs at most 4 arguments")
- }
- err := Convert(args[0], &cond)
- if err != nil {
- return env.Fail(err)
- }
- ifBlock, ok = (args[1]).(Block)
- if !ok {
- return env.FailString("if: second argument must be a block")
- }
- elseIndex := 2
- if 2 < len(args) {
- // look for an else keyword but don't mind if it really is else
- _, ok = (args[2]).(Word)
- if ok {
- // block after else keyword
- elseIndex = 3
- }
- }
- if elseIndex < len(args) {
- // There should be an else block...
- elseBlock, ok = (args[elseIndex]).(Block)
- if !ok {
- return env.FailString("if: missing else block")
- }
- haveElse = true
- }
- if cond {
- return ifBlock.Eval(env, args...)
- } else {
- if haveElse {
- return elseBlock.Eval(env, args...)
- } else {
- return nil, nil
- }
- }
- }
- func switch_(env *Environment, args ...Value) (Value, Effect) {
- var defaultBlock Block
- var haveDefault bool = false
- if len(args) < 3 {
- return env.FailString("switch needs at least 3 arguments")
- }
- compareTo := args[0]
- for i := 2; i < len(args); i += 2 {
- case_ := args[i-1]
- block, blockOk := args[i].(Block)
- if !blockOk {
- return env.FailString("switch: argument ${1} is not a block",
- Int(i))
- }
- if kw, kwOk := case_.(Word); kwOk && kw.String() == "default" {
- if haveDefault {
- return env.FailString("switch: duplicate default block ${1}",
- Int(i))
- }
- haveDefault = true
- defaultBlock = block
- } else {
- if compareTo.String() == case_.String() {
- return block.Eval(env, args...)
- }
- }
- }
- if haveDefault {
- return defaultBlock.Eval(env, args...)
- }
- return nil, nil
- }
- func while(env *Environment, args ...Value) (Value, Effect) {
- var blockRes Value
- var blockEff Effect
- if len(args) != 2 {
- return env.FailString("while needs exactly 3 arguments")
- }
- cond, condOk := args[0].(Block)
- block, blockOk := args[1].(Block)
- if !condOk {
- return env.FailString("while condition must be a block")
- }
- if !blockOk {
- return env.FailString("while body must be a block")
- }
- for res, eff := cond.Eval(env, args...); ValToBool(res); res, eff = cond.Eval(env, args...) {
- if eff != nil && eff.Flow() > NormalFlow {
- return res, eff
- }
- blockRes, blockEff = block.Eval(env, args...)
- if blockEff != nil && blockEff.Flow() > NormalFlow {
- return blockRes, blockEff
- }
- }
- return blockRes, blockEff
- }
- func rescue(env *Environment, args ...Value) (Value, Effect) {
- var block Block
- err := Args(args, &block)
- if err != nil {
- return env.Fail(err)
- }
- return env.Prevent(block)
- }
- func set(env *Environment, args ...Value) (Value, Effect) {
- if len(args) < 2 {
- return env.FailString("set needs at 2 arguments")
- }
- if args[0] == nil {
- return env.FailString("set $1 is nil")
- }
- return env.Set(args[0].String(), args[1])
- }
- func let(env *Environment, args ...Value) (Value, Effect) {
- if len(args) < 2 {
- return env.FailString("def needs at 2 arguments")
- }
- if args[0] == nil {
- return env.FailString("def $1 is nil")
- }
- return env.Define(args[0].String(), args[1], 1)
- }
- func get(env *Environment, val ...Value) (Value, Effect) {
- if len(val) < 1 {
- return env.FailString("get needs at least 1 argument")
- }
- target := val[0].String()
- return env.Lookup(target), nil
- }
- func list(env *Environment, args ...Value) (Value, Effect) {
- return List(args), nil
- }
- func sadd(env *Environment, args ...Value) (Value, Effect) {
- var value Value
- var str String
- err := Args(args, &str, &value)
- if err != nil {
- return env.Fail(err)
- }
- str = str + String(value.String())
- return str, nil
- }
- func sget(env *Environment, args ...Value) (Value, Effect) {
- var index int
- var str String
- err := Args(args, &str, &index)
- if err != nil {
- return env.Fail(err)
- }
- runes := []rune(str)
- if (index < 0) || (index >= len(runes)) {
- return env.FailString("index out of range")
- }
- return Int(runes[index]), nil
- }
- func runes(env *Environment, args ...Value) (Value, Effect) {
- var str String
- err := Args(args, &str)
- if err != nil {
- return env.Fail(err)
- }
- res := List{}
- runes := []rune(str)
- for i := 0; i < len(runes); i++ {
- res = append(res, Int(runes[i]))
- }
- return res, nil
- }
- func wire(env *Environment, args ...Value) (Value, Effect) {
- var str String
- for i := 0; i < len(args); i++ {
- var ch Int
- err := Convert(args[i], &ch)
- if err != nil {
- return str, err
- }
- str = str + String([]rune{rune(ch)})
- }
- return str, nil
- }
- func slen(env *Environment, args ...Value) (Value, Effect) {
- var str String
- err := Args(args, &str)
- if err != nil {
- return env.Fail(err)
- }
- runes := []rune(str)
- return Int(len(runes)), nil
- }
- func ladd(env *Environment, args ...Value) (Value, Effect) {
- var value Value
- var list List
- err := Args(args, &list, &value)
- if err != nil {
- return env.Fail(err)
- }
- list = append(list, value)
- return list, nil
- }
- func lget(env *Environment, args ...Value) (Value, Effect) {
- var index int
- var list List
- err := Args(args, &list, &index)
- if err != nil {
- return env.Fail(err)
- }
- if (index < 0) || (index >= len(list)) {
- return env.FailString("index out of range")
- }
- return list[index], nil
- }
- func lset(env *Environment, args ...Value) (Value, Effect) {
- var index int
- var list List
- var val Value
- err := Args(args, &list, &index, &val)
- if err != nil {
- return env.Fail(err)
- }
- if (index < 0) || (index >= len(list)) {
- return env.FailString("index out of range")
- }
- list[index] = val
- return list[index], nil
- }
- func llen(env *Environment, args ...Value) (Value, Effect) {
- var list List
- err := Args(args, &list)
- if err != nil {
- return env.Fail(err)
- }
- return Int(len(list)), nil
- }
- func lsort(env *Environment, args ...Value) (Value, Effect) {
- var list List
- err := Args(args, &list)
- if err != nil {
- return env.Fail(err)
- }
- return list.SortStrings(), nil
- }
- func leach(env *Environment, args ...Value) (Value, Effect) {
- var list List
- var key Word
- var name Word
- var block Block
- err := Args(args, &list, &key, &name, &block)
- if err != nil {
- return env.Fail(err)
- }
- for i, v := range list {
- env.Define(key.String(), Int(i), 0)
- env.Define(name.String(), v, 0)
- bval, berr := block.Eval(env, args...)
- if berr != nil {
- return bval, berr
- }
- }
- return list, nil
- }
- func lslice(env *Environment, args ...Value) (Value, Effect) {
- var list List
- var from Int
- var to Int
- err := Args(args, &list, &from, &to)
- if err != nil {
- return env.Fail(err)
- }
- length := Int(len(list))
- if length == 0 {
- return list, nil
- }
- if from < 0 {
- from = length - from
- }
- if to < 0 {
- from = length - from
- }
- if from >= length {
- from = length - 1
- }
- if to >= length {
- to = length - 1
- }
- if from > to {
- from, to = to, from
- }
- return list[from:to], nil
- }
- func map_(env *Environment, args ...Value) (Value, Effect) {
- res := make(Map)
- for i := 1; i < len(args); i += 2 {
- key := args[i-1]
- val := args[i]
- res[key.String()] = val
- }
- return res, nil
- }
- func mget(env *Environment, args ...Value) (Value, Effect) {
- var index string
- var hmap Map
- err := Args(args, &hmap, &index)
- if err != nil {
- return env.Fail(err)
- }
- return hmap[index], nil
- }
- func mset(env *Environment, args ...Value) (Value, Effect) {
- var index string
- var hmap Map
- var val Value
- err := Args(args, &hmap, &index, &val)
- if err != nil {
- return env.Fail(err)
- }
- hmap[index] = val
- return hmap[index], nil
- }
- func mkeys(env *Environment, args ...Value) (Value, Effect) {
- var hmap Map
- err := Args(args, &hmap)
- if err != nil {
- return env.Fail(err)
- }
- res := List{}
- for k, _ := range hmap {
- res = append(res, String(k))
- }
- return res, nil
- }
- func meach(env *Environment, args ...Value) (Value, Effect) {
- var map_ Map
- var key Word
- var name Word
- var block Block
- err := Args(args, &map_, &key, &name, &block)
- if err != nil {
- return env.Fail(err)
- }
- miter := Map{}
- for k, v := range map_ {
- miter[k] = v
- }
- for k, v := range miter {
- env.Define(key.String(), String(k), 0)
- env.Define(name.String(), v, 0)
- bval, beff := block.Eval(env, args...)
- if beff != nil {
- return bval, beff
- }
- }
- return map_, nil
- }
- func expand(env *Environment, args ...Value) (Value, Effect) {
- var msg string
- err := Args(args, &msg)
- if err != nil {
- return env.Fail(err)
- }
- res := env.Interpolate(msg)
- return String(res), nil
- }
- func help(env *Environment, args ...Value) (Value, Effect) {
- var name string
- err := Args(args, &name)
- if err != nil {
- return env.Fail(err)
- }
- helpMap := env.Lookup("HELP")
- if helpMap == nil {
- env.Printi("help: $1:No help available 1.\n", String(name))
- return nil, err
- }
- if name == "all" {
- keys := helpMap.(Map).SortedKeys()
- for _, k := range keys {
- v := helpMap.(Map)[k.String()]
- env.Printi("$1: $2\n", k, v)
- }
- return nil, nil
- }
- msg, ok := helpMap.(Map)[name]
- if ok {
- env.Printi("help: $1:\n$2\n", String(name), msg)
- } else {
- env.Printi("help: $1:No help available 2.\n", String(name))
- }
- return msg, nil
- }
- func explain(env *Environment, args ...Value) (Value, Effect) {
- var name string
- var help String
- err := Args(args, &name, &help)
- if err != nil {
- return env.Fail(err)
- }
- helpMap := env.Lookup("HELP")
- if helpMap == nil {
- helpMap = make(Map)
- }
- helpMap.(Map)[name] = help
- env.Define("HELP", helpMap, -1)
- return help, nil
- }
- func overload(env *Environment, args ...Value) (Value, Effect) {
- var name string
- var target Value
- err := Args(args, &name, &target)
- if err != nil {
- return env.Fail(err)
- }
- if len(args) < 3 {
- return env.FailString("overload needs at least 3 arguments")
- }
- return env.Overload(name, target, args[2:len(args)])
- }
- func (env *Environment) Register(name string,
- f func(e *Environment, args ...Value) (Value, Effect), help string) {
- env.Define(name, Proc(f), -1)
- explain(env, String(name), String(help))
- }
- func (env *Environment) RegisterBuiltins() {
- env.Define("true", Bool(true), -1)
- env.Define("false", Bool(false), -1)
- env.Register("sadd", sadd, "returns a string with $2 appended to string $1")
- env.Register("sget", sget, "gets a rune from a string by index")
- env.Register("slen", slen, "returns the length of a string")
- env.Register("iadd", iadd, "adds two integers together")
- env.Register("band", band, `returns true if $1 and $2 arguments are true`)
- env.Register("bor", bor, `returns true if $1 or $2 arguments are true`)
- env.Register("bxor", bxor, `returns true if $1 and $2 are different booleans`)
- env.Register("bnot", bnot, `returns true if $1 is false and false otherwise`)
- env.Register("ladd", ladd, "returns a list with $2 appended to List $1")
- env.Register("list", list, "creates a new array list")
- env.Register("lget", lget, "gets a value from a list by index")
- env.Register("lset", lset, "sets a value to a list by index and value")
- env.Register("llen", llen, "returns the length of a list")
- env.Register("lsort", lsort, "returns the List $1 sorted by string value")
- env.Register("leach", leach, "calls the block $4 for each entry in the list")
- env.Register("lslice", lslice, "slices the list $1 from $2 to $3")
- env.Register("iadd", iadd, "adds and Ints to and Int")
- env.Register("isub", isub, "subtracts an Int from an Int")
- env.Register("imul", imul, "multiplies an Ints by an Int")
- env.Register("idiv", idiv, "divides an Int by an Int")
- env.Register("ilt", ilt, "checks if $1 < $2, where $1 and $2 must be Int")
- env.Register("ile", ile, "checks if $1 <= $2, where $1 and $2 must be Int")
- env.Register("igt", igt, "checks if $1 > $2, where $1 and $2 must be Int")
- env.Register("ige", ige, "checks if $1 >= $2, where $1 and $2 must be Int")
- env.Register("ieq", ieq, "checks if $1 == $2, where $1 and $2 must be Int")
- env.Register("seq", seq, "checks if [str $1] == [str $2]")
- env.Register("str", str, "converts $1 to String")
- env.Register("wire", wire, "converts unicode character indexes or runes to String")
- env.Register("runes", runes, "converts String to alist of character indexes or runes")
- env.Register("int", int_, "converts $1 to Int")
- env.Register("inc", inc, "increments the named integer $1")
- env.Register("dec", dec, "decrements the named integer $1")
- env.Register("map", map_, "creates a new hash map")
- env.Register("mget", mget, "gets a value from a map by key")
- env.Register("mset", mset, "sets a value to a map by key and value")
- env.Register("mkeys", mkeys, "returns all keys of a map as an unsorted list")
- env.Register("meach", meach, "calls the block $4 for each entry in the map")
- env.Register("p", p, "print debug output")
- env.Register("print", print_, "print to the environnment's current writer with interpolation")
- env.Register("write", write, "write to the environnment's current writer")
- env.Register("to", to, "define a procedure")
- env.Register("do", do, "execute a command $1 with arguments in $2 as array")
- env.Register("ret", ret, "return from a procedure")
- env.Register("return", ret, "return from a procedure")
- env.Register("break", break_, "return from a block")
- env.Register("val", val, "gets the value of a value")
- env.Register("let", let, "creates a new vavariable with given value")
- env.Register("set", set, "sets an existing variable")
- env.Register("get", get, "get the contents of a variable")
- env.Register("help", help, "get help for a procedure")
- env.Register("explain", explain, "set the help for a procedure")
- env.Register("expand", expand, "interpolate strings from environment")
- env.Register("fail", fail, "fail execution of a procedure")
- env.Register("rescue", rescue, "call $1 as the error handler on failure")
- env.Register("if", if_, "if runs $1 if $0 is true, otherwise runs $2")
- env.Register("isnil", isnil, "returns true if $1 is nil, false if not")
- env.Register("switch", switch_, "selects one of many cases")
- env.Register("type", type_, "returns $1 converted to a type")
- env.Register("teq", teq, "checks if $1 and $2 are exactly the same type")
- env.Register("typeof", typeof_, "returns the type of $1 or Unknown if not known")
- env.Register("nop", nop, "does nothing and returns nil")
- env.Register("overload", overload, "creates a command overload named $1 targeting $2 for the types following $2")
- }
- // This function registers builtins that make Attl turing complete
- // Not to be used in situations where this is undesirable.
- func (env *Environment) RegisterTuringCompleteBuiltins() {
- env.Register("while", while, "executes $2 while $1 returns true")
- }
|