github.com/mattn/anko@v0.1.10/core/core.go (about) 1 // Package core implements core interface for anko script. 2 package core 3 4 import ( 5 "fmt" 6 "io/ioutil" 7 "reflect" 8 9 "github.com/mattn/anko/env" 10 "github.com/mattn/anko/parser" 11 "github.com/mattn/anko/vm" 12 ) 13 14 // Import defines core language builtins - keys, range, println, etc. 15 func Import(e *env.Env) *env.Env { 16 e.Define("keys", func(v interface{}) []interface{} { 17 rv := reflect.ValueOf(v) 18 if rv.Kind() == reflect.Interface { 19 rv = rv.Elem() 20 } 21 mapKeysValue := rv.MapKeys() 22 mapKeys := make([]interface{}, len(mapKeysValue)) 23 for i := 0; i < len(mapKeysValue); i++ { 24 mapKeys[i] = mapKeysValue[i].Interface() 25 } 26 return mapKeys 27 }) 28 29 e.Define("range", func(args ...int64) []int64 { 30 var start, stop int64 31 var step int64 = 1 32 33 switch len(args) { 34 case 0: 35 panic("range expected at least 1 argument, got 0") 36 case 1: 37 stop = args[0] 38 case 2: 39 start = args[0] 40 stop = args[1] 41 case 3: 42 start = args[0] 43 stop = args[1] 44 step = args[2] 45 if step == 0 { 46 panic("range argument 3 must not be zero") 47 } 48 default: 49 panic(fmt.Sprintf("range expected at most 3 arguments, got %d", len(args))) 50 } 51 52 arr := []int64{} 53 for i := start; (step > 0 && i < stop) || (step < 0 && i > stop); i += step { 54 arr = append(arr, i) 55 } 56 return arr 57 }) 58 59 e.Define("typeOf", func(v interface{}) string { 60 return reflect.TypeOf(v).String() 61 }) 62 63 e.Define("kindOf", func(v interface{}) string { 64 typeOf := reflect.TypeOf(v) 65 if typeOf == nil { 66 return "nil" 67 } 68 return typeOf.Kind().String() 69 }) 70 71 e.Define("defined", func(s string) bool { 72 _, err := e.Get(s) 73 return err == nil 74 }) 75 76 e.Define("load", func(s string) interface{} { 77 body, err := ioutil.ReadFile(s) 78 if err != nil { 79 panic(err) 80 } 81 scanner := new(parser.Scanner) 82 scanner.Init(string(body)) 83 stmts, err := parser.Parse(scanner) 84 if err != nil { 85 if pe, ok := err.(*parser.Error); ok { 86 pe.Filename = s 87 panic(pe) 88 } 89 panic(err) 90 } 91 rv, err := vm.Run(e, nil, stmts) 92 if err != nil { 93 panic(err) 94 } 95 return rv 96 }) 97 98 e.Define("print", fmt.Print) 99 e.Define("println", fmt.Println) 100 e.Define("printf", fmt.Printf) 101 102 ImportToX(e) 103 104 return e 105 }