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  }