github.com/masahide/goansible@v0.0.0-20160116054156-01eac649e9f2/lisp/builtin.go (about)

     1  package lisp
     2  
     3  import "fmt"
     4  
     5  type Builtin struct{}
     6  
     7  var builtin = Builtin{}
     8  
     9  var builtin_commands = map[string]string{
    10  	"+":       "Add",
    11  	"-":       "Sub",
    12  	"*":       "Mul",
    13  	"==":      "Eq",
    14  	">":       "Gt",
    15  	"<":       "Lt",
    16  	">=":      "Gte",
    17  	"<=":      "Lte",
    18  	"display": "Display",
    19  	"cons":    "Cons",
    20  	"car":     "Car",
    21  	"cdr":     "Cdr",
    22  }
    23  
    24  func (Builtin) Display(vars ...Value) (Value, error) {
    25  	if len(vars) == 1 {
    26  		fmt.Println(vars[0])
    27  	} else {
    28  		return Nil, fmt.Errorf("Badly formatted arguments: %v", vars)
    29  	}
    30  	return vars[0], nil
    31  }
    32  
    33  func (Builtin) Cons(vars ...Value) (Value, error) {
    34  	if len(vars) == 2 {
    35  		cons := Cons{&vars[0], &vars[1]}
    36  		return Value{consValue, &cons}, nil
    37  	} else {
    38  		return Nil, fmt.Errorf("Badly formatted arguments: %v", vars)
    39  	}
    40  }
    41  
    42  func (Builtin) Car(vars ...Value) (Value, error) {
    43  	if len(vars) == 1 && vars[0].typ == consValue {
    44  		cons := vars[0].Cons()
    45  		return *cons.car, nil
    46  	} else {
    47  		return Nil, fmt.Errorf("Badly formatted arguments: %v", vars)
    48  	}
    49  }
    50  
    51  func (Builtin) Cdr(vars ...Value) (Value, error) {
    52  	if len(vars) == 1 && vars[0].typ == consValue {
    53  		cons := vars[0].Cons()
    54  		return *cons.cdr, nil
    55  	} else {
    56  		return Nil, fmt.Errorf("Badly formatted arguments: %v", vars)
    57  	}
    58  }
    59  
    60  func (Builtin) Add(vars ...Value) (Value, error) {
    61  	var sum int64
    62  	for _, v := range vars {
    63  		if v.typ == numberValue {
    64  			sum += v.Number()
    65  		} else {
    66  			return Nil, fmt.Errorf("Badly formatted arguments: %v", vars)
    67  		}
    68  	}
    69  	return Value{numberValue, sum}, nil
    70  }
    71  
    72  func (Builtin) Sub(vars ...Value) (Value, error) {
    73  	if vars[0].typ != numberValue {
    74  		return Nil, fmt.Errorf("Badly formatted arguments: %v", vars)
    75  	}
    76  	sum := vars[0].Number()
    77  	for _, v := range vars[1:] {
    78  		if v.typ == numberValue {
    79  			sum -= v.Number()
    80  		} else {
    81  			return Nil, fmt.Errorf("Badly formatted arguments: %v", vars)
    82  		}
    83  	}
    84  	return Value{numberValue, sum}, nil
    85  }
    86  
    87  func (Builtin) Mul(vars ...Value) (Value, error) {
    88  	if vars[0].typ != numberValue {
    89  		return Nil, fmt.Errorf("Badly formatted arguments: %v", vars)
    90  	}
    91  	sum := vars[0].Number()
    92  	for _, v := range vars[1:] {
    93  		if v.typ == numberValue {
    94  			sum *= v.Number()
    95  		} else {
    96  			return Nil, fmt.Errorf("Badly formatted arguments: %v", vars)
    97  		}
    98  	}
    99  	return Value{numberValue, sum}, nil
   100  }
   101  
   102  func (Builtin) Eq(vars ...Value) (Value, error) {
   103  	for i := 1; i < len(vars); i++ {
   104  		v1 := vars[i-1]
   105  		v2 := vars[i]
   106  
   107  		if v1.typ != v2.typ {
   108  			return Nil, fmt.Errorf("Badly formatted arguments: %v", vars)
   109  		} else if v1.typ == numberValue {
   110  			if v1.Number() != v2.Number() {
   111  				return False, nil
   112  			}
   113  		} else if v1.typ == stringValue {
   114  			if v1.String() != v2.String() {
   115  				return False, nil
   116  			}
   117  		} else {
   118  			return Nil, fmt.Errorf("Unsupported argument type: %v", vars)
   119  		}
   120  	}
   121  	return True, nil
   122  }
   123  
   124  func (Builtin) Gt(vars ...Value) (Value, error) {
   125  	for i := 1; i < len(vars); i++ {
   126  		v1 := vars[i-1]
   127  		v2 := vars[i]
   128  		if v1.typ != numberValue || v2.typ != numberValue {
   129  			return Nil, fmt.Errorf("Badly formatted arguments: %v", vars)
   130  		} else if !(v1.Number() > v2.Number()) {
   131  			return False, nil
   132  		}
   133  	}
   134  	return True, nil
   135  }
   136  
   137  func (Builtin) Lt(vars ...Value) (Value, error) {
   138  	for i := 1; i < len(vars); i++ {
   139  		v1 := vars[i-1]
   140  		v2 := vars[i]
   141  		if v1.typ != numberValue || v2.typ != numberValue {
   142  			return Nil, fmt.Errorf("Badly formatted arguments: %v", vars)
   143  		} else if !(v1.Number() < v2.Number()) {
   144  			return False, nil
   145  		}
   146  	}
   147  	return True, nil
   148  }
   149  
   150  func (Builtin) Gte(vars ...Value) (Value, error) {
   151  	for i := 1; i < len(vars); i++ {
   152  		v1 := vars[i-1]
   153  		v2 := vars[i]
   154  		if v1.typ != numberValue || v2.typ != numberValue {
   155  			return Nil, fmt.Errorf("Badly formatted arguments: %v", vars)
   156  		} else if !(v1.Number() >= v2.Number()) {
   157  			return False, nil
   158  		}
   159  	}
   160  	return True, nil
   161  }
   162  
   163  func (Builtin) Lte(vars ...Value) (Value, error) {
   164  	for i := 1; i < len(vars); i++ {
   165  		v1 := vars[i-1]
   166  		v2 := vars[i]
   167  		if v1.typ != numberValue || v2.typ != numberValue {
   168  			return Nil, fmt.Errorf("Badly formatted arguments: %v", vars)
   169  		} else if !(v1.Number() <= v2.Number()) {
   170  			return False, nil
   171  		}
   172  	}
   173  	return True, nil
   174  }