github.com/unidoc/unidoc@v2.2.0+incompatible/pdf/ps/object.go (about)

     1  /*
     2   * This file is subject to the terms and conditions defined in
     3   * file 'LICENSE.md', which is part of this source code package.
     4   */
     5  
     6  // Package ps implements a small subset of the postscript language used in PDF for type 4 functions.
     7  // Only objects are integers, real numbers, and boolean values only.
     8  //
     9  package ps
    10  
    11  import (
    12  	"errors"
    13  	"fmt"
    14  	"math"
    15  )
    16  
    17  type PSObject interface {
    18  	Duplicate() PSObject
    19  	DebugString() string // Only for debugging.
    20  	String() string
    21  }
    22  
    23  // Integer.
    24  type PSInteger struct {
    25  	Val int
    26  }
    27  
    28  func (this *PSInteger) Duplicate() PSObject {
    29  	obj := PSInteger{}
    30  	obj.Val = this.Val
    31  	return &obj
    32  }
    33  
    34  func (this *PSInteger) DebugString() string {
    35  	return fmt.Sprintf("int:%d", this.Val)
    36  }
    37  
    38  func (this *PSInteger) String() string {
    39  	return fmt.Sprintf("%d", this.Val)
    40  }
    41  
    42  // Real number.
    43  type PSReal struct {
    44  	Val float64
    45  }
    46  
    47  func (this *PSReal) DebugString() string {
    48  	return fmt.Sprintf("real:%.5f", this.Val)
    49  }
    50  
    51  func (this *PSReal) String() string {
    52  	return fmt.Sprintf("%.5f", this.Val)
    53  }
    54  
    55  func (this *PSReal) Duplicate() PSObject {
    56  	obj := PSReal{}
    57  	obj.Val = this.Val
    58  	return &obj
    59  }
    60  
    61  // Bool.
    62  type PSBoolean struct {
    63  	Val bool
    64  }
    65  
    66  func (this *PSBoolean) DebugString() string {
    67  	return fmt.Sprintf("bool:%v", this.Val)
    68  }
    69  
    70  func (this *PSBoolean) String() string {
    71  	return fmt.Sprintf("%v", this.Val)
    72  }
    73  
    74  func (this *PSBoolean) Duplicate() PSObject {
    75  	obj := PSBoolean{}
    76  	obj.Val = this.Val
    77  	return &obj
    78  }
    79  
    80  // A Postscript program is a series of PS objects (arguments, commands, programs etc).
    81  type PSProgram []PSObject
    82  
    83  func NewPSProgram() *PSProgram {
    84  	return &PSProgram{}
    85  }
    86  
    87  func (this *PSProgram) Append(obj PSObject) {
    88  	*this = append(*this, obj)
    89  }
    90  
    91  func (this *PSProgram) DebugString() string {
    92  	s := "{ "
    93  	for _, obj := range *this {
    94  		s += obj.DebugString()
    95  		s += " "
    96  	}
    97  	s += "}"
    98  
    99  	return s
   100  }
   101  
   102  func (this *PSProgram) String() string {
   103  	s := "{ "
   104  	for _, obj := range *this {
   105  		s += obj.String()
   106  		s += " "
   107  	}
   108  	s += "}"
   109  
   110  	return s
   111  }
   112  
   113  func (this *PSProgram) Duplicate() PSObject {
   114  	prog := &PSProgram{}
   115  	for _, obj := range *this {
   116  		prog.Append(obj.Duplicate())
   117  	}
   118  	return prog
   119  }
   120  
   121  func (this *PSProgram) Exec(stack *PSStack) error {
   122  	for _, obj := range *this {
   123  		var err error
   124  		if number, isInt := obj.(*PSInteger); isInt {
   125  			err = stack.Push(number)
   126  		} else if number, isReal := obj.(*PSReal); isReal {
   127  			err = stack.Push(number)
   128  		} else if val, isBool := obj.(*PSBoolean); isBool {
   129  			err = stack.Push(val)
   130  		} else if function, isFunc := obj.(*PSProgram); isFunc {
   131  			err = stack.Push(function)
   132  		} else if op, isOp := obj.(*PSOperand); isOp {
   133  			err = op.Exec(stack)
   134  		} else {
   135  			return ErrTypeCheck
   136  		}
   137  		if err != nil {
   138  			return err
   139  		}
   140  	}
   141  	return nil
   142  }
   143  
   144  // Operand.
   145  type PSOperand string
   146  
   147  func (this *PSOperand) DebugString() string {
   148  	return fmt.Sprintf("op:'%s'", *this)
   149  }
   150  
   151  func (this *PSOperand) String() string {
   152  	return fmt.Sprintf("%s", *this)
   153  }
   154  
   155  func (this *PSOperand) Duplicate() PSObject {
   156  	s := *this
   157  	return &s
   158  }
   159  
   160  func (this *PSOperand) Exec(stack *PSStack) error {
   161  	err := errors.New("Unsupported operand")
   162  	switch *this {
   163  	case "abs":
   164  		err = this.Abs(stack)
   165  	case "add":
   166  		err = this.Add(stack)
   167  	case "and":
   168  		err = this.And(stack)
   169  	case "atan":
   170  		err = this.Atan(stack)
   171  
   172  	case "bitshift":
   173  		err = this.Bitshift(stack)
   174  
   175  	case "ceiling":
   176  		err = this.Ceiling(stack)
   177  	case "copy":
   178  		err = this.Copy(stack)
   179  	case "cos":
   180  		err = this.Cos(stack)
   181  	case "cvi":
   182  		err = this.Cvi(stack)
   183  	case "cvr":
   184  		err = this.Cvr(stack)
   185  
   186  	case "div":
   187  		err = this.Div(stack)
   188  	case "dup":
   189  		err = this.Dup(stack)
   190  
   191  	case "eq":
   192  		err = this.Eq(stack)
   193  	case "exch":
   194  		err = this.Exch(stack)
   195  	case "exp":
   196  		err = this.Exp(stack)
   197  
   198  	case "floor":
   199  		err = this.Floor(stack)
   200  
   201  	case "ge":
   202  		err = this.Ge(stack)
   203  	case "gt":
   204  		err = this.Gt(stack)
   205  
   206  	case "idiv":
   207  		err = this.IDiv(stack)
   208  	case "if":
   209  		err = this.If(stack)
   210  	case "ifelse":
   211  		err = this.IfElse(stack)
   212  	case "index":
   213  		err = this.Index(stack)
   214  
   215  	case "le":
   216  		err = this.Le(stack)
   217  	case "log":
   218  		err = this.Log(stack)
   219  	case "ln":
   220  		err = this.Ln(stack)
   221  	case "lt":
   222  		err = this.Lt(stack)
   223  
   224  	case "mod":
   225  		err = this.Mod(stack)
   226  	case "mul":
   227  		err = this.Mul(stack)
   228  
   229  	case "ne":
   230  		err = this.Ne(stack)
   231  	case "neg":
   232  		err = this.Neg(stack)
   233  	case "not":
   234  		err = this.Not(stack)
   235  
   236  	case "or":
   237  		err = this.Or(stack)
   238  
   239  	case "pop":
   240  		err = this.Pop(stack)
   241  
   242  	case "round":
   243  		err = this.Round(stack)
   244  	case "roll":
   245  		err = this.Roll(stack)
   246  
   247  	case "sin":
   248  		err = this.Sin(stack)
   249  	case "sqrt":
   250  		err = this.Sqrt(stack)
   251  	case "sub":
   252  		err = this.Sub(stack)
   253  
   254  	case "truncate":
   255  		err = this.Truncate(stack)
   256  
   257  	case "xor":
   258  		err = this.Xor(stack)
   259  	}
   260  
   261  	return err
   262  }
   263  
   264  //////
   265  // Operation implementations
   266  
   267  // Absolute value.
   268  func (this *PSOperand) Abs(stack *PSStack) error {
   269  	obj, err := stack.Pop()
   270  	if err != nil {
   271  		return err
   272  	}
   273  
   274  	if num, is := obj.(*PSReal); is {
   275  		val := num.Val
   276  		if val < 0 {
   277  			err = stack.Push(MakeReal(-val))
   278  		} else {
   279  			err = stack.Push(MakeReal(val))
   280  		}
   281  	} else if num, is := obj.(*PSInteger); is {
   282  		val := num.Val
   283  		if val < 0 {
   284  			err = stack.Push(MakeInteger(-val))
   285  		} else {
   286  			err = stack.Push(MakeInteger(val))
   287  		}
   288  	} else {
   289  		return ErrTypeCheck
   290  	}
   291  
   292  	return err
   293  }
   294  
   295  // 5 27 add -> 32
   296  func (this *PSOperand) Add(stack *PSStack) error {
   297  	obj1, err := stack.Pop()
   298  	if err != nil {
   299  		return err
   300  	}
   301  
   302  	obj2, err := stack.Pop()
   303  	if err != nil {
   304  		return err
   305  	}
   306  
   307  	real1, isReal1 := obj1.(*PSReal)
   308  	int1, isInt1 := obj1.(*PSInteger)
   309  	if !isReal1 && !isInt1 {
   310  		return ErrTypeCheck
   311  	}
   312  
   313  	real2, isReal2 := obj2.(*PSReal)
   314  	int2, isInt2 := obj2.(*PSInteger)
   315  	if !isReal2 && !isInt2 {
   316  		return ErrTypeCheck
   317  	}
   318  
   319  	// If both numbers integers -> integer output.
   320  	if isInt1 && isInt2 {
   321  		result := int1.Val + int2.Val
   322  		err := stack.Push(MakeInteger(result))
   323  		return err
   324  	}
   325  
   326  	// Otherwise -> real output.
   327  	var result float64 = 0
   328  	if isReal1 {
   329  		result = real1.Val
   330  	} else {
   331  		result = float64(int1.Val)
   332  	}
   333  
   334  	if isReal2 {
   335  		result += real2.Val
   336  	} else {
   337  		result += float64(int2.Val)
   338  	}
   339  
   340  	err = stack.Push(MakeReal(result))
   341  	return err
   342  }
   343  
   344  // And operation.
   345  // if bool: returns the logical "and" of the inputs
   346  // bool1 bool2 and -> bool3
   347  // if int: returns the bitwise "and" of the inputs
   348  // int1 int2 and -> int3
   349  func (this *PSOperand) And(stack *PSStack) error {
   350  	obj1, err := stack.Pop()
   351  	if err != nil {
   352  		return err
   353  	}
   354  
   355  	obj2, err := stack.Pop()
   356  	if err != nil {
   357  		return err
   358  	}
   359  
   360  	// Boolean inputs.
   361  	if bool1, is := obj1.(*PSBoolean); is {
   362  		bool2, ok := obj2.(*PSBoolean)
   363  		if !ok {
   364  			return ErrTypeCheck
   365  		}
   366  		err = stack.Push(MakeBool(bool1.Val && bool2.Val)) // logical and
   367  		return err
   368  	}
   369  
   370  	// Integer inputs
   371  	if int1, is := obj1.(*PSInteger); is {
   372  		int2, ok := obj2.(*PSInteger)
   373  		if !ok {
   374  			return ErrTypeCheck
   375  		}
   376  		err = stack.Push(MakeInteger(int1.Val & int2.Val)) // bitwise and
   377  		return err
   378  	}
   379  
   380  	return ErrTypeCheck
   381  }
   382  
   383  // den num atan -> atan(num/den) in degrees.
   384  // result is a real value.
   385  func (this *PSOperand) Atan(stack *PSStack) error {
   386  	// Denominator
   387  	den, err := stack.PopNumberAsFloat64()
   388  	if err != nil {
   389  		return err
   390  	}
   391  
   392  	// Numerator
   393  	num, err := stack.PopNumberAsFloat64()
   394  	if err != nil {
   395  		return err
   396  	}
   397  
   398  	// special cases.
   399  	// atan(inf) -> 90
   400  	// atan(-inf) -> 270
   401  	if den == 0 {
   402  		var err error
   403  		if num < 0 {
   404  			err = stack.Push(MakeReal(270))
   405  		} else {
   406  			err = stack.Push(MakeReal(90))
   407  		}
   408  		return err
   409  	}
   410  
   411  	ratio := num / den
   412  	angleDeg := math.Atan(ratio) * 180 / math.Pi
   413  
   414  	err = stack.Push(MakeReal(angleDeg))
   415  	return err
   416  }
   417  
   418  // bitshift
   419  // int1 shift bitshift -> int2
   420  func (this *PSOperand) Bitshift(stack *PSStack) error {
   421  	shift, err := stack.PopInteger()
   422  	if err != nil {
   423  		return err
   424  	}
   425  
   426  	int1, err := stack.PopInteger()
   427  	if err != nil {
   428  		return err
   429  	}
   430  
   431  	var result int
   432  
   433  	if shift >= 0 {
   434  		result = int1 << uint(shift)
   435  	} else {
   436  		result = int1 >> uint(-shift)
   437  	}
   438  
   439  	err = stack.Push(MakeInteger(result))
   440  	return err
   441  }
   442  
   443  // Ceiling of number.
   444  // num1 ceiling -> num2
   445  // The type of the result is the same as of the operand.
   446  func (this *PSOperand) Ceiling(stack *PSStack) error {
   447  	obj, err := stack.Pop()
   448  	if err != nil {
   449  		return err
   450  	}
   451  
   452  	if num, is := obj.(*PSReal); is {
   453  		err = stack.Push(MakeReal(math.Ceil(num.Val)))
   454  	} else if num, is := obj.(*PSInteger); is {
   455  		err = stack.Push(MakeInteger(num.Val))
   456  	} else {
   457  		err = ErrTypeCheck
   458  	}
   459  
   460  	return err
   461  }
   462  
   463  // Copy
   464  // any1 ... anyn n copy -> any1 ... anyn any1 ... anyn
   465  func (this *PSOperand) Copy(stack *PSStack) error {
   466  	n, err := stack.PopInteger()
   467  	if err != nil {
   468  		return err
   469  	}
   470  
   471  	if n < 0 {
   472  		return ErrRangeCheck
   473  	}
   474  
   475  	if n > len(*stack) {
   476  		return ErrRangeCheck
   477  	}
   478  
   479  	*stack = append(*stack, (*stack)[len(*stack)-n:]...)
   480  	return nil
   481  }
   482  
   483  // Cosine
   484  // angle cos -> real
   485  // Angle is in degrees
   486  func (this *PSOperand) Cos(stack *PSStack) error {
   487  	angle, err := stack.PopNumberAsFloat64()
   488  	if err != nil {
   489  		return err
   490  	}
   491  
   492  	result := math.Cos(angle * math.Pi / 180.0)
   493  	err = stack.Push(MakeReal(result))
   494  	return err
   495  }
   496  
   497  // Convert to integer
   498  func (this *PSOperand) Cvi(stack *PSStack) error {
   499  	obj, err := stack.Pop()
   500  	if err != nil {
   501  		return err
   502  	}
   503  
   504  	if num, is := obj.(*PSReal); is {
   505  		val := int(num.Val)
   506  		err = stack.Push(MakeInteger(val))
   507  	} else if num, is := obj.(*PSInteger); is {
   508  		val := num.Val
   509  		err = stack.Push(MakeInteger(val))
   510  	} else {
   511  		return ErrTypeCheck
   512  	}
   513  
   514  	return err
   515  }
   516  
   517  // Convert number tor real
   518  func (this *PSOperand) Cvr(stack *PSStack) error {
   519  	obj, err := stack.Pop()
   520  	if err != nil {
   521  		return err
   522  	}
   523  
   524  	if num, is := obj.(*PSReal); is {
   525  		err = stack.Push(MakeReal(num.Val))
   526  	} else if num, is := obj.(*PSInteger); is {
   527  		err = stack.Push(MakeReal(float64(num.Val)))
   528  	} else {
   529  		return ErrTypeCheck
   530  	}
   531  
   532  	return err
   533  }
   534  
   535  func (this *PSOperand) Div(stack *PSStack) error {
   536  	obj1, err := stack.Pop()
   537  	if err != nil {
   538  		return err
   539  	}
   540  
   541  	obj2, err := stack.Pop()
   542  	if err != nil {
   543  		return err
   544  	}
   545  
   546  	real1, isReal1 := obj1.(*PSReal)
   547  	int1, isInt1 := obj1.(*PSInteger)
   548  	if !isReal1 && !isInt1 {
   549  		return ErrTypeCheck
   550  	}
   551  	// Cannot be 0.
   552  	if isReal1 && real1.Val == 0 {
   553  		return ErrUndefinedResult
   554  	}
   555  	if isInt1 && int1.Val == 0 {
   556  		return ErrUndefinedResult
   557  	}
   558  
   559  	real2, isReal2 := obj2.(*PSReal)
   560  	int2, isInt2 := obj2.(*PSInteger)
   561  	if !isReal2 && !isInt2 {
   562  		return ErrTypeCheck
   563  	}
   564  
   565  	// Float output.
   566  	var result float64 = 0
   567  	if isReal2 {
   568  		result = real2.Val
   569  	} else {
   570  		result = float64(int2.Val)
   571  	}
   572  
   573  	if isReal1 {
   574  		result /= real1.Val
   575  	} else {
   576  		result /= float64(int1.Val)
   577  	}
   578  
   579  	err = stack.Push(MakeReal(result))
   580  	return err
   581  }
   582  
   583  // Duplicates the top object on the stack (dup)
   584  func (this *PSOperand) Dup(stack *PSStack) error {
   585  	obj, err := stack.Pop()
   586  	if err != nil {
   587  		return err
   588  	}
   589  
   590  	// Push it back.
   591  	err = stack.Push(obj)
   592  	if err != nil {
   593  		return err
   594  	}
   595  	// Push the duplicate.
   596  	err = stack.Push(obj.Duplicate())
   597  	return err
   598  }
   599  
   600  // Check for equality.
   601  // any1 any2 eq bool
   602  func (this *PSOperand) Eq(stack *PSStack) error {
   603  	obj1, err := stack.Pop()
   604  	if err != nil {
   605  		return err
   606  	}
   607  
   608  	obj2, err := stack.Pop()
   609  	if err != nil {
   610  		return err
   611  	}
   612  
   613  	// bool, real, int
   614  	// if bool, both must be bool
   615  	bool1, isBool1 := obj1.(*PSBoolean)
   616  	bool2, isBool2 := obj2.(*PSBoolean)
   617  	if isBool1 || isBool2 {
   618  		var err error
   619  		if isBool1 && isBool2 {
   620  			err = stack.Push(MakeBool(bool1.Val == bool2.Val))
   621  		} else {
   622  			// Type mismatch -> false
   623  			err = stack.Push(MakeBool(false))
   624  		}
   625  		return err
   626  	}
   627  
   628  	var val1 float64
   629  	var val2 float64
   630  
   631  	if number, is := obj1.(*PSInteger); is {
   632  		val1 = float64(number.Val)
   633  	} else if number, is := obj1.(*PSReal); is {
   634  		val1 = number.Val
   635  	} else {
   636  		return ErrTypeCheck
   637  	}
   638  
   639  	if number, is := obj2.(*PSInteger); is {
   640  		val2 = float64(number.Val)
   641  	} else if number, is := obj2.(*PSReal); is {
   642  		val2 = number.Val
   643  	} else {
   644  		return ErrTypeCheck
   645  	}
   646  
   647  	if math.Abs(val2-val1) < TOLERANCE {
   648  		err = stack.Push(MakeBool(true))
   649  	} else {
   650  		err = stack.Push(MakeBool(false))
   651  	}
   652  
   653  	return err
   654  }
   655  
   656  // Exchange the top two elements of the stack (exch)
   657  func (this *PSOperand) Exch(stack *PSStack) error {
   658  	top, err := stack.Pop()
   659  	if err != nil {
   660  		return err
   661  	}
   662  
   663  	next, err := stack.Pop()
   664  	if err != nil {
   665  		return err
   666  	}
   667  
   668  	err = stack.Push(top)
   669  	if err != nil {
   670  		return err
   671  	}
   672  	err = stack.Push(next)
   673  
   674  	return err
   675  }
   676  
   677  // base exponent exp -> base^exp
   678  // Raises base to exponent power.
   679  // The result is a real number.
   680  func (this *PSOperand) Exp(stack *PSStack) error {
   681  	exponent, err := stack.PopNumberAsFloat64()
   682  	if err != nil {
   683  		return err
   684  	}
   685  
   686  	base, err := stack.PopNumberAsFloat64()
   687  	if err != nil {
   688  		return err
   689  	}
   690  
   691  	if math.Abs(exponent) < 1 && base < 0 {
   692  		return ErrUndefinedResult
   693  	}
   694  
   695  	result := math.Pow(base, exponent)
   696  	err = stack.Push(MakeReal(result))
   697  
   698  	return err
   699  }
   700  
   701  // Floor of number.
   702  func (this *PSOperand) Floor(stack *PSStack) error {
   703  	obj, err := stack.Pop()
   704  	if err != nil {
   705  		return err
   706  	}
   707  
   708  	if num, is := obj.(*PSReal); is {
   709  		err = stack.Push(MakeReal(math.Floor(num.Val)))
   710  	} else if num, is := obj.(*PSInteger); is {
   711  		err = stack.Push(MakeInteger(num.Val))
   712  	} else {
   713  		return ErrTypeCheck
   714  	}
   715  
   716  	return err
   717  }
   718  
   719  // Greater than or equal
   720  // num1 num2 ge -> bool; num1 >= num2
   721  func (this *PSOperand) Ge(stack *PSStack) error {
   722  	num2, err := stack.PopNumberAsFloat64()
   723  	if err != nil {
   724  		return err
   725  	}
   726  
   727  	num1, err := stack.PopNumberAsFloat64()
   728  	if err != nil {
   729  		return err
   730  	}
   731  
   732  	// Check equlity.
   733  	if math.Abs(num1-num2) < TOLERANCE {
   734  		err := stack.Push(MakeBool(true))
   735  		return err
   736  	} else if num1 > num2 {
   737  		err := stack.Push(MakeBool(true))
   738  		return err
   739  	} else {
   740  		err := stack.Push(MakeBool(false))
   741  		return err
   742  	}
   743  }
   744  
   745  // Greater than
   746  // num1 num2 gt -> bool; num1 > num2
   747  func (this *PSOperand) Gt(stack *PSStack) error {
   748  	num2, err := stack.PopNumberAsFloat64()
   749  	if err != nil {
   750  		return err
   751  	}
   752  
   753  	num1, err := stack.PopNumberAsFloat64()
   754  	if err != nil {
   755  		return err
   756  	}
   757  
   758  	// Check equlity.
   759  	if math.Abs(num1-num2) < TOLERANCE {
   760  		err := stack.Push(MakeBool(false))
   761  		return err
   762  	} else if num1 > num2 {
   763  		err := stack.Push(MakeBool(true))
   764  		return err
   765  	} else {
   766  		err := stack.Push(MakeBool(false))
   767  		return err
   768  	}
   769  }
   770  
   771  // Integral division
   772  // 25 3 div -> 8
   773  func (this *PSOperand) IDiv(stack *PSStack) error {
   774  	obj1, err := stack.Pop()
   775  	if err != nil {
   776  		return err
   777  	}
   778  
   779  	obj2, err := stack.Pop()
   780  	if err != nil {
   781  		return err
   782  	}
   783  
   784  	int1, ok := obj1.(*PSInteger)
   785  	if !ok {
   786  		return ErrTypeCheck
   787  	}
   788  	if int1.Val == 0 {
   789  		return ErrUndefinedResult
   790  	}
   791  
   792  	int2, ok := obj2.(*PSInteger)
   793  	if !ok {
   794  		return ErrTypeCheck
   795  	}
   796  
   797  	result := int2.Val / int1.Val
   798  	err = stack.Push(MakeInteger(result))
   799  
   800  	return err
   801  }
   802  
   803  // If conditional
   804  // bool proc if -> run proc() if bool is true
   805  func (this *PSOperand) If(stack *PSStack) error {
   806  	obj1, err := stack.Pop()
   807  	if err != nil {
   808  		return err
   809  	}
   810  	obj2, err := stack.Pop()
   811  	if err != nil {
   812  		return err
   813  	}
   814  
   815  	// Type checks.
   816  	proc, ok := obj1.(*PSProgram)
   817  	if !ok {
   818  		return ErrTypeCheck
   819  	}
   820  	condition, ok := obj2.(*PSBoolean)
   821  	if !ok {
   822  		return ErrTypeCheck
   823  	}
   824  
   825  	// Run proc if condition is true.
   826  	if condition.Val {
   827  		err := proc.Exec(stack)
   828  		return err
   829  	}
   830  
   831  	return nil
   832  }
   833  
   834  // If else conditional
   835  // bool proc1 proc2 ifelse -> execute proc1() if bool is true, otherwise proc2()
   836  func (this *PSOperand) IfElse(stack *PSStack) error {
   837  	obj1, err := stack.Pop()
   838  	if err != nil {
   839  		return err
   840  	}
   841  	obj2, err := stack.Pop()
   842  	if err != nil {
   843  		return err
   844  	}
   845  	obj3, err := stack.Pop()
   846  	if err != nil {
   847  		return err
   848  	}
   849  
   850  	// Type checks.
   851  	proc2, ok := obj1.(*PSProgram)
   852  	if !ok {
   853  		return ErrTypeCheck
   854  	}
   855  	proc1, ok := obj2.(*PSProgram)
   856  	if !ok {
   857  		return ErrTypeCheck
   858  	}
   859  	condition, ok := obj3.(*PSBoolean)
   860  	if !ok {
   861  		return ErrTypeCheck
   862  	}
   863  
   864  	// Run proc if condition is true.
   865  	if condition.Val {
   866  		err := proc1.Exec(stack)
   867  		return err
   868  	} else {
   869  		err := proc2.Exec(stack)
   870  		return err
   871  	}
   872  }
   873  
   874  // Add a copy of the nth object in the stack to the top.
   875  // any_n ... any_0 n index -> any_n ... any_0 any_n
   876  // index from 0
   877  func (this *PSOperand) Index(stack *PSStack) error {
   878  	obj, err := stack.Pop()
   879  	if err != nil {
   880  		return err
   881  	}
   882  
   883  	n, ok := obj.(*PSInteger)
   884  	if !ok {
   885  		return ErrTypeCheck
   886  	}
   887  
   888  	if n.Val < 0 {
   889  		return ErrRangeCheck
   890  	}
   891  
   892  	if n.Val > len(*stack)-1 {
   893  		return ErrStackUnderflow
   894  	}
   895  
   896  	objN := (*stack)[len(*stack)-1-n.Val]
   897  
   898  	err = stack.Push(objN.Duplicate())
   899  	return err
   900  }
   901  
   902  // Less or equal
   903  // num1 num2 le -> bool; num1 <= num2
   904  func (this *PSOperand) Le(stack *PSStack) error {
   905  	num2, err := stack.PopNumberAsFloat64()
   906  	if err != nil {
   907  		return err
   908  	}
   909  
   910  	num1, err := stack.PopNumberAsFloat64()
   911  	if err != nil {
   912  		return err
   913  	}
   914  
   915  	// Check equlity.
   916  	if math.Abs(num1-num2) < TOLERANCE {
   917  		err := stack.Push(MakeBool(true))
   918  		return err
   919  	} else if num1 < num2 {
   920  		err := stack.Push(MakeBool(true))
   921  		return err
   922  	} else {
   923  		err := stack.Push(MakeBool(false))
   924  		return err
   925  	}
   926  }
   927  
   928  // num log -> real
   929  func (this *PSOperand) Log(stack *PSStack) error {
   930  	// Value
   931  	val, err := stack.PopNumberAsFloat64()
   932  	if err != nil {
   933  		return err
   934  	}
   935  
   936  	result := math.Log10(val)
   937  	err = stack.Push(MakeReal(result))
   938  	return err
   939  }
   940  
   941  // num ln -> ln(num)
   942  // The result is a real number.
   943  func (this *PSOperand) Ln(stack *PSStack) error {
   944  	// Value
   945  	val, err := stack.PopNumberAsFloat64()
   946  	if err != nil {
   947  		return err
   948  	}
   949  
   950  	result := math.Log(val)
   951  	err = stack.Push(MakeReal(result))
   952  	return err
   953  }
   954  
   955  // Less than
   956  // num1 num2 lt -> bool; num1 < num2
   957  func (this *PSOperand) Lt(stack *PSStack) error {
   958  	num2, err := stack.PopNumberAsFloat64()
   959  	if err != nil {
   960  		return err
   961  	}
   962  
   963  	num1, err := stack.PopNumberAsFloat64()
   964  	if err != nil {
   965  		return err
   966  	}
   967  
   968  	// Check equlity.
   969  	if math.Abs(num1-num2) < TOLERANCE {
   970  		err := stack.Push(MakeBool(false))
   971  		return err
   972  	} else if num1 < num2 {
   973  		err := stack.Push(MakeBool(true))
   974  		return err
   975  	} else {
   976  		err := stack.Push(MakeBool(false))
   977  		return err
   978  	}
   979  }
   980  
   981  // 12 10 mod -> 2
   982  func (this *PSOperand) Mod(stack *PSStack) error {
   983  	obj1, err := stack.Pop()
   984  	if err != nil {
   985  		return err
   986  	}
   987  
   988  	obj2, err := stack.Pop()
   989  	if err != nil {
   990  		return err
   991  	}
   992  
   993  	int1, ok := obj1.(*PSInteger)
   994  	if !ok {
   995  		return ErrTypeCheck
   996  	}
   997  	if int1.Val == 0 {
   998  		return ErrUndefinedResult
   999  	}
  1000  
  1001  	int2, ok := obj2.(*PSInteger)
  1002  	if !ok {
  1003  		return ErrTypeCheck
  1004  	}
  1005  
  1006  	result := int2.Val % int1.Val
  1007  	err = stack.Push(MakeInteger(result))
  1008  	return err
  1009  }
  1010  
  1011  // 6 8 mul -> 48
  1012  func (this *PSOperand) Mul(stack *PSStack) error {
  1013  	obj1, err := stack.Pop()
  1014  	if err != nil {
  1015  		return err
  1016  	}
  1017  
  1018  	obj2, err := stack.Pop()
  1019  	if err != nil {
  1020  		return err
  1021  	}
  1022  
  1023  	real1, isReal1 := obj1.(*PSReal)
  1024  	int1, isInt1 := obj1.(*PSInteger)
  1025  	if !isReal1 && !isInt1 {
  1026  		return ErrTypeCheck
  1027  	}
  1028  
  1029  	real2, isReal2 := obj2.(*PSReal)
  1030  	int2, isInt2 := obj2.(*PSInteger)
  1031  	if !isReal2 && !isInt2 {
  1032  		return ErrTypeCheck
  1033  	}
  1034  
  1035  	// If both numbers integers -> integer output.
  1036  	if isInt1 && isInt2 {
  1037  		result := int1.Val * int2.Val
  1038  		err := stack.Push(MakeInteger(result))
  1039  		return err
  1040  	}
  1041  
  1042  	// Otherwise -> real output.
  1043  	var result float64 = 0
  1044  	if isReal1 {
  1045  		result = real1.Val
  1046  	} else {
  1047  		result = float64(int1.Val)
  1048  	}
  1049  
  1050  	if isReal2 {
  1051  		result *= real2.Val
  1052  	} else {
  1053  		result *= float64(int2.Val)
  1054  	}
  1055  
  1056  	err = stack.Push(MakeReal(result))
  1057  	return err
  1058  }
  1059  
  1060  // Not equal (inverse of eq)
  1061  // any1 any2 ne -> bool
  1062  func (this *PSOperand) Ne(stack *PSStack) error {
  1063  	// Simply call equate and then negate the result.
  1064  	// Implementing directly could be more efficient, but probably not a big deal in most cases.
  1065  	err := this.Eq(stack)
  1066  	if err != nil {
  1067  		return err
  1068  	}
  1069  
  1070  	err = this.Not(stack)
  1071  	return err
  1072  }
  1073  
  1074  // Negate
  1075  // 6 neg -> -6
  1076  func (this *PSOperand) Neg(stack *PSStack) error {
  1077  	obj, err := stack.Pop()
  1078  	if err != nil {
  1079  		return err
  1080  	}
  1081  
  1082  	if real, isReal := obj.(*PSReal); isReal {
  1083  		err = stack.Push(MakeReal(-real.Val))
  1084  		return err
  1085  	} else if inum, isInt := obj.(*PSInteger); isInt {
  1086  		err = stack.Push(MakeInteger(-inum.Val))
  1087  		return err
  1088  
  1089  	} else {
  1090  		return ErrTypeCheck
  1091  	}
  1092  }
  1093  
  1094  // Logical/bitwise negation
  1095  // bool1 not -> bool2 (logical)
  1096  // int1 not ->  int2 (bitwise)
  1097  func (this *PSOperand) Not(stack *PSStack) error {
  1098  	obj, err := stack.Pop()
  1099  	if err != nil {
  1100  		return err
  1101  	}
  1102  
  1103  	if bool1, is := obj.(*PSBoolean); is {
  1104  		err = stack.Push(MakeBool(!bool1.Val))
  1105  		return err
  1106  	} else if int1, isInt := obj.(*PSInteger); isInt {
  1107  		err = stack.Push(MakeInteger(^int1.Val))
  1108  		return err
  1109  	} else {
  1110  		return ErrTypeCheck
  1111  	}
  1112  }
  1113  
  1114  // OR logical/bitwise operation.
  1115  // bool1 bool2 or -> bool3 (logical or)
  1116  // int1 int2 or -> int3 (bitwise or)
  1117  func (this *PSOperand) Or(stack *PSStack) error {
  1118  	obj1, err := stack.Pop()
  1119  	if err != nil {
  1120  		return err
  1121  	}
  1122  
  1123  	obj2, err := stack.Pop()
  1124  	if err != nil {
  1125  		return err
  1126  	}
  1127  
  1128  	// Boolean inputs (logical).
  1129  	if bool1, is := obj1.(*PSBoolean); is {
  1130  		bool2, ok := obj2.(*PSBoolean)
  1131  		if !ok {
  1132  			return ErrTypeCheck
  1133  		}
  1134  		err = stack.Push(MakeBool(bool1.Val || bool2.Val))
  1135  		return err
  1136  	}
  1137  
  1138  	// Integer inputs (bitwise).
  1139  	if int1, is := obj1.(*PSInteger); is {
  1140  		int2, ok := obj2.(*PSInteger)
  1141  		if !ok {
  1142  			return ErrTypeCheck
  1143  		}
  1144  		err = stack.Push(MakeInteger(int1.Val | int2.Val))
  1145  		return err
  1146  	}
  1147  
  1148  	return ErrTypeCheck
  1149  }
  1150  
  1151  // Remove the top element on the stack (pop)
  1152  func (this *PSOperand) Pop(stack *PSStack) error {
  1153  	_, err := stack.Pop()
  1154  	if err != nil {
  1155  		return err
  1156  	}
  1157  	return nil
  1158  }
  1159  
  1160  // Round number off.
  1161  // num1 round -> num2
  1162  func (this *PSOperand) Round(stack *PSStack) error {
  1163  	obj, err := stack.Pop()
  1164  	if err != nil {
  1165  		return err
  1166  	}
  1167  
  1168  	if num, is := obj.(*PSReal); is {
  1169  		err = stack.Push(MakeReal(math.Floor(num.Val + 0.5)))
  1170  	} else if num, is := obj.(*PSInteger); is {
  1171  		err = stack.Push(MakeInteger(num.Val))
  1172  	} else {
  1173  		return ErrTypeCheck
  1174  	}
  1175  
  1176  	return err
  1177  }
  1178  
  1179  // Roll stack contents (num dir roll)
  1180  // num: number of elements, dir: direction
  1181  // 7 8 9 3  1 roll -> 9 7 8
  1182  // 7 8 9 3 -1 roll -> 8 9 7
  1183  // n j roll
  1184  func (this *PSOperand) Roll(stack *PSStack) error {
  1185  	obj1, err := stack.Pop()
  1186  	if err != nil {
  1187  		return err
  1188  	}
  1189  
  1190  	obj2, err := stack.Pop()
  1191  	if err != nil {
  1192  		return err
  1193  	}
  1194  
  1195  	j, ok := obj1.(*PSInteger)
  1196  	if !ok {
  1197  		return ErrTypeCheck
  1198  	}
  1199  
  1200  	n, ok := obj2.(*PSInteger)
  1201  	if !ok {
  1202  		return ErrTypeCheck
  1203  	}
  1204  	if n.Val < 0 {
  1205  		return ErrRangeCheck
  1206  	}
  1207  	if n.Val == 0 || n.Val == 1 {
  1208  		// Do nothing..
  1209  		return nil
  1210  	}
  1211  	if n.Val > len(*stack) {
  1212  		return ErrStackUnderflow
  1213  	}
  1214  
  1215  	for i := 0; i < abs(j.Val); i++ {
  1216  		var substack []PSObject
  1217  
  1218  		substack = (*stack)[len(*stack)-(n.Val) : len(*stack)]
  1219  		if j.Val > 0 {
  1220  			// if j > 0; put the top element on bottom of the substack
  1221  			top := substack[len(substack)-1]
  1222  			substack = append([]PSObject{top}, substack[0:len(substack)-1]...)
  1223  		} else {
  1224  			// if j < 0: put the bottom element on top
  1225  			bottom := substack[len(substack)-n.Val]
  1226  			substack = append(substack[1:], bottom)
  1227  		}
  1228  
  1229  		s := append((*stack)[0:len(*stack)-n.Val], substack...)
  1230  		stack = &s
  1231  	}
  1232  
  1233  	return nil
  1234  }
  1235  
  1236  // Sine.
  1237  // angle sin -> real
  1238  // Angle is in degrees
  1239  func (this *PSOperand) Sin(stack *PSStack) error {
  1240  	angle, err := stack.PopNumberAsFloat64()
  1241  	if err != nil {
  1242  		return err
  1243  	}
  1244  
  1245  	result := math.Sin(angle * math.Pi / 180.0)
  1246  	err = stack.Push(MakeReal(result))
  1247  	return err
  1248  }
  1249  
  1250  // Square root.
  1251  // num sqrt -> real; real=sqrt(num)
  1252  // The result is a real number.
  1253  func (this *PSOperand) Sqrt(stack *PSStack) error {
  1254  	val, err := stack.PopNumberAsFloat64()
  1255  	if err != nil {
  1256  		return err
  1257  	}
  1258  
  1259  	if val < 0 {
  1260  		return ErrRangeCheck
  1261  	}
  1262  
  1263  	result := math.Sqrt(val)
  1264  	err = stack.Push(MakeReal(result))
  1265  	return err
  1266  }
  1267  
  1268  // 8.3 6.6 sub -> 1.7 (real)
  1269  // 8 6.3 sub -> 1.7 (real)
  1270  // 8 6 sub -> 2 (int)
  1271  func (this *PSOperand) Sub(stack *PSStack) error {
  1272  	obj1, err := stack.Pop()
  1273  	if err != nil {
  1274  		return err
  1275  	}
  1276  
  1277  	obj2, err := stack.Pop()
  1278  	if err != nil {
  1279  		return err
  1280  	}
  1281  
  1282  	real1, isReal1 := obj1.(*PSReal)
  1283  	int1, isInt1 := obj1.(*PSInteger)
  1284  	if !isReal1 && !isInt1 {
  1285  		return ErrTypeCheck
  1286  	}
  1287  
  1288  	real2, isReal2 := obj2.(*PSReal)
  1289  	int2, isInt2 := obj2.(*PSInteger)
  1290  	if !isReal2 && !isInt2 {
  1291  		return ErrTypeCheck
  1292  	}
  1293  
  1294  	// If both numbers integers -> integer output.
  1295  	if isInt1 && isInt2 {
  1296  		result := int2.Val - int1.Val
  1297  		err := stack.Push(MakeInteger(result))
  1298  		return err
  1299  	}
  1300  
  1301  	// Otherwise -> real output.
  1302  	var result float64 = 0
  1303  	if isReal2 {
  1304  		result = real2.Val
  1305  	} else {
  1306  		result = float64(int2.Val)
  1307  	}
  1308  
  1309  	if isReal1 {
  1310  		result -= real1.Val
  1311  	} else {
  1312  		result -= float64(int1.Val)
  1313  	}
  1314  
  1315  	err = stack.Push(MakeReal(result))
  1316  	return err
  1317  }
  1318  
  1319  // Truncate number.
  1320  // num1 truncate -> num2
  1321  // The resulting number is the same type as the input.
  1322  func (this *PSOperand) Truncate(stack *PSStack) error {
  1323  	obj, err := stack.Pop()
  1324  	if err != nil {
  1325  		return err
  1326  	}
  1327  
  1328  	if num, is := obj.(*PSReal); is {
  1329  		truncated := int(num.Val)
  1330  		err = stack.Push(MakeReal(float64(truncated)))
  1331  	} else if num, is := obj.(*PSInteger); is {
  1332  		err = stack.Push(MakeInteger(num.Val))
  1333  	} else {
  1334  		return ErrTypeCheck
  1335  	}
  1336  
  1337  	return err
  1338  }
  1339  
  1340  // XOR logical/bitwise operation.
  1341  // bool1 bool2 xor -> bool3 (logical xor)
  1342  // int1 int2 xor -> int3 (bitwise xor)
  1343  func (this *PSOperand) Xor(stack *PSStack) error {
  1344  	obj1, err := stack.Pop()
  1345  	if err != nil {
  1346  		return err
  1347  	}
  1348  
  1349  	obj2, err := stack.Pop()
  1350  	if err != nil {
  1351  		return err
  1352  	}
  1353  
  1354  	// Boolean inputs (logical).
  1355  	if bool1, is := obj1.(*PSBoolean); is {
  1356  		bool2, ok := obj2.(*PSBoolean)
  1357  		if !ok {
  1358  			return ErrTypeCheck
  1359  		}
  1360  		err = stack.Push(MakeBool(bool1.Val != bool2.Val))
  1361  		return err
  1362  	}
  1363  
  1364  	// Integer inputs (bitwise).
  1365  	if int1, is := obj1.(*PSInteger); is {
  1366  		int2, ok := obj2.(*PSInteger)
  1367  		if !ok {
  1368  			return ErrTypeCheck
  1369  		}
  1370  		err = stack.Push(MakeInteger(int1.Val ^ int2.Val))
  1371  		return err
  1372  	}
  1373  
  1374  	return ErrTypeCheck
  1375  }