simpler vm
This commit is contained in:
@@ -70,31 +70,33 @@ func (ao *Array) Less(i, j int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (ao *Array) Add(other Object) (Object, error) {
|
||||
if other.Type() != ao.Type() {
|
||||
return nil, NewBinaryOpError(ao, other, "+")
|
||||
func (a *Array) Add(other Object) (Object, error) {
|
||||
switch obj := other.(type) {
|
||||
case *Array:
|
||||
var elements []Object
|
||||
elements = append(elements, a.Elements...)
|
||||
elements = append(elements, obj.Elements...)
|
||||
|
||||
return &Array{Elements: elements}, nil
|
||||
default:
|
||||
return nil, NewBinaryOpError(a, other, "+")
|
||||
}
|
||||
|
||||
var elements []Object
|
||||
elements = append(elements, ao.Elements...)
|
||||
elements = append(elements, other.(*Array).Elements...)
|
||||
|
||||
return &Array{Elements: elements}, nil
|
||||
|
||||
}
|
||||
|
||||
func (ao *Array) Mul(other Object) (Object, error) {
|
||||
if other.Type() != IntegerType {
|
||||
return nil, NewBinaryOpError(ao, other, "*")
|
||||
func (a *Array) Mul(other Object) (Object, error) {
|
||||
switch obj := other.(type) {
|
||||
case Integer:
|
||||
var elements []Object
|
||||
N := int(obj.Value)
|
||||
for i := 0; i < N; i++ {
|
||||
elements = append(elements, a.Elements...)
|
||||
}
|
||||
|
||||
return &Array{Elements: elements}, nil
|
||||
default:
|
||||
return nil, NewBinaryOpError(a, other, "*")
|
||||
}
|
||||
|
||||
var elements []Object
|
||||
N := int(other.(Integer).Value)
|
||||
for i := 0; i < N; i++ {
|
||||
elements = append(elements, ao.Elements...)
|
||||
}
|
||||
|
||||
return &Array{Elements: elements}, nil
|
||||
}
|
||||
|
||||
func (ao *Array) Get(index Object) (Object, error) {
|
||||
|
||||
@@ -45,51 +45,61 @@ func (i Integer) Sub(other Object) (Object, error) {
|
||||
}
|
||||
|
||||
func (i Integer) Mul(other Object) (Object, error) {
|
||||
switch other.Type() {
|
||||
case IntegerType:
|
||||
return Integer{i.Value * other.(Integer).Value}, nil
|
||||
case StringType:
|
||||
return other.(Mul).Mul(i)
|
||||
case ArrayType:
|
||||
return other.(Mul).Mul(i)
|
||||
switch obj := other.(type) {
|
||||
case Integer:
|
||||
return Integer{i.Value * obj.Value}, nil
|
||||
case String:
|
||||
return obj.Mul(i)
|
||||
case *Array:
|
||||
return obj.Mul(i)
|
||||
default:
|
||||
return nil, NewBinaryOpError(i, other, "*")
|
||||
}
|
||||
}
|
||||
|
||||
func (i Integer) Div(other Object) (Object, error) {
|
||||
if !AssertTypes(other, IntegerType) {
|
||||
switch obj := other.(type) {
|
||||
case Integer:
|
||||
return Integer{i.Value / obj.Value}, nil
|
||||
default:
|
||||
return nil, NewBinaryOpError(i, other, "/")
|
||||
}
|
||||
return Integer{i.Value / other.(Integer).Value}, nil
|
||||
}
|
||||
|
||||
func (i Integer) Mod(other Object) (Object, error) {
|
||||
if !AssertTypes(other, IntegerType) {
|
||||
switch obj := other.(type) {
|
||||
case Integer:
|
||||
return Integer{i.Value % obj.Value}, nil
|
||||
default:
|
||||
return nil, NewBinaryOpError(i, other, "%")
|
||||
}
|
||||
return Integer{i.Value % other.(Integer).Value}, nil
|
||||
}
|
||||
|
||||
func (i Integer) BitwiseOr(other Object) (Object, error) {
|
||||
if !AssertTypes(other, IntegerType) {
|
||||
switch obj := other.(type) {
|
||||
case Integer:
|
||||
return Integer{i.Value | obj.Value}, nil
|
||||
default:
|
||||
return nil, NewBinaryOpError(i, other, "|")
|
||||
}
|
||||
return Integer{i.Value | other.(Integer).Value}, nil
|
||||
}
|
||||
|
||||
func (i Integer) BitwiseXor(other Object) (Object, error) {
|
||||
if !AssertTypes(other, IntegerType) {
|
||||
switch obj := other.(type) {
|
||||
case Integer:
|
||||
return Integer{i.Value ^ obj.Value}, nil
|
||||
default:
|
||||
return nil, NewBinaryOpError(i, other, "^")
|
||||
}
|
||||
return Integer{i.Value ^ other.(Integer).Value}, nil
|
||||
}
|
||||
|
||||
func (i Integer) BitwiseAnd(other Object) (Object, error) {
|
||||
if !AssertTypes(other, IntegerType) {
|
||||
switch obj := other.(type) {
|
||||
case Integer:
|
||||
return Integer{i.Value & obj.Value}, nil
|
||||
default:
|
||||
return nil, NewBinaryOpError(i, other, "")
|
||||
}
|
||||
return Integer{i.Value & other.(Integer).Value}, nil
|
||||
}
|
||||
|
||||
func (i Integer) BitwiseNot() Object {
|
||||
@@ -97,17 +107,21 @@ func (i Integer) BitwiseNot() Object {
|
||||
}
|
||||
|
||||
func (i Integer) LeftShift(other Object) (Object, error) {
|
||||
if !AssertTypes(other, IntegerType) {
|
||||
switch obj := other.(type) {
|
||||
case Integer:
|
||||
return Integer{i.Value << obj.Value}, nil
|
||||
default:
|
||||
return nil, NewBinaryOpError(i, other, "<<")
|
||||
}
|
||||
return Integer{i.Value << other.(Integer).Value}, nil
|
||||
}
|
||||
|
||||
func (i Integer) RightShift(other Object) (Object, error) {
|
||||
if !AssertTypes(other, IntegerType) {
|
||||
switch obj := other.(type) {
|
||||
case Integer:
|
||||
return Integer{i.Value >> obj.Value}, nil
|
||||
default:
|
||||
return nil, NewBinaryOpError(i, other, ">>")
|
||||
}
|
||||
return Integer{i.Value >> other.(Integer).Value}, nil
|
||||
}
|
||||
|
||||
func (i Integer) LogicalNot() Object {
|
||||
|
||||
@@ -54,91 +54,6 @@ func (t Type) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
// Add is the interface for binary addition
|
||||
type Add interface {
|
||||
Add(other Object) (Object, error)
|
||||
}
|
||||
|
||||
// Sub is the interface for binary subtraction
|
||||
type Sub interface {
|
||||
Sub(other Object) (Object, error)
|
||||
}
|
||||
|
||||
// Mul is the interface for binary multiplication
|
||||
type Mul interface {
|
||||
Mul(other Object) (Object, error)
|
||||
}
|
||||
|
||||
// Div is the interface for binary division
|
||||
type Div interface {
|
||||
Div(other Object) (Object, error)
|
||||
}
|
||||
|
||||
// Mod is the interface for binary modulo
|
||||
type Mod interface {
|
||||
Mod(other Object) (Object, error)
|
||||
}
|
||||
|
||||
// LogicalOr is the interface for logical or
|
||||
type LogicalOr interface {
|
||||
LogicalOr(other Object) (Object, error)
|
||||
}
|
||||
|
||||
// LogicalAnd is the interface for logical and
|
||||
type LogicalAnd interface {
|
||||
LogicalAnd(other Object) (Object, error)
|
||||
}
|
||||
|
||||
// BitwiseOr is the interface for bitwise or
|
||||
type BitwiseOr interface {
|
||||
BitwiseOr(other Object) (Object, error)
|
||||
}
|
||||
|
||||
// BitwiseAnd is the interface for bitwise and
|
||||
type BitwiseAnd interface {
|
||||
BitwiseAnd(other Object) (Object, error)
|
||||
}
|
||||
|
||||
// BitwiseXor is the interface for bitwise xor
|
||||
type BitwiseXor interface {
|
||||
BitwiseXor(other Object) (Object, error)
|
||||
}
|
||||
|
||||
// BitwiseNot is the interface for bitwise not
|
||||
type BitwiseNot interface {
|
||||
BitwiseNot() Object
|
||||
}
|
||||
|
||||
// LeftShift is the interface for bitwise left shift
|
||||
type LeftShift interface {
|
||||
LeftShift(other Object) (Object, error)
|
||||
}
|
||||
|
||||
// RightShift is the interface for bitwise right shift
|
||||
type RightShift interface {
|
||||
RightShift(other Object) (Object, error)
|
||||
}
|
||||
|
||||
// LogicalNot is the interface for logical not
|
||||
type LogicalNot interface {
|
||||
LogicalNot() Object
|
||||
}
|
||||
|
||||
// Negate is the interface for unary negation
|
||||
type Negate interface {
|
||||
Negate() Object
|
||||
}
|
||||
|
||||
// Setter is the interface for assigning a value to an index
|
||||
type Setter interface {
|
||||
Set(index, value Object) error
|
||||
}
|
||||
|
||||
// Getter is the interface for getting a value from an index
|
||||
type Getter interface {
|
||||
Get(index Object) (Object, error)
|
||||
}
|
||||
|
||||
// Comparable is the interface for comparing two Object and their underlying
|
||||
// values. It is the responsibility of the caller (left) to check for types.
|
||||
// Returns `true` iif the types and values are identical, `false` otherwise.
|
||||
@@ -146,13 +61,6 @@ type Comparable interface {
|
||||
Compare(other Object) int
|
||||
}
|
||||
|
||||
// Sizeable is the interface for returning the size of an Object.
|
||||
// Object(s) that have a valid size must implement this interface and the
|
||||
// Len() method.
|
||||
type Sizeable interface {
|
||||
Len() int
|
||||
}
|
||||
|
||||
// Immutable is the interface for all immutable objects which must implement
|
||||
// the Clone() method used by binding names to values.
|
||||
type Immutable interface {
|
||||
|
||||
@@ -35,17 +35,21 @@ func (s String) String() string {
|
||||
}
|
||||
|
||||
func (s String) Add(other Object) (Object, error) {
|
||||
if !AssertTypes(other, StringType) {
|
||||
switch obj := other.(type) {
|
||||
case String:
|
||||
return String{s.Value + obj.Value}, nil
|
||||
default:
|
||||
return nil, NewBinaryOpError(s, other, "+")
|
||||
}
|
||||
return String{s.Value + other.(String).Value}, nil
|
||||
}
|
||||
|
||||
func (s String) Mul(other Object) (Object, error) {
|
||||
if !AssertTypes(other, IntegerType) {
|
||||
switch obj := other.(type) {
|
||||
case Integer:
|
||||
return String{strings.Repeat(s.Value, int(obj.Value))}, nil
|
||||
default:
|
||||
return nil, NewBinaryOpError(s, other, "*")
|
||||
}
|
||||
return String{strings.Repeat(s.Value, int(other.(Integer).Value))}, nil
|
||||
}
|
||||
|
||||
func (s String) Get(index Object) (Object, error) {
|
||||
|
||||
Reference in New Issue
Block a user