Position Independent Source Code

Diff
Login

Differences From Artifact [dc6db86c51]:

To Artifact [d64d73fe80]:


     1      1   package main
     2      2   
     3      3   import (
     4      4   	"bytes"
     5      5   	"fmt"
            6  +	"reflect"
     6      7   	"strconv"
     7      8   )
     8      9   
     9     10   type stackEntry interface {
    10     11   	String() string
    11     12   	Type() string
    12     13   }
    13     14   
    14     15   type lenable interface {
    15     16   	Length() int
    16     17   }
    17     18   
           19  +func runEq(m *machine) error {
           20  +	a := m.popValue()
           21  +	b := m.popValue()
           22  +	m.pushValue(Boolean(eq(a, b)))
           23  +	return nil
           24  +}
           25  +
           26  +// Check if two arrays are
           27  +func arrayRefEq(a, b Array) bool {
           28  +	if len(a) != len(b) {
           29  +		return false
           30  +	}
           31  +	if len(a) == 0 {
           32  +		return true
           33  +	}
           34  +	return &a[0] == &b[0]
           35  +}
           36  +
           37  +func mapRefEq(a, b Dict) bool {
           38  +	if len(a) != len(b) {
           39  +		return false
           40  +	}
           41  +	if len(a) == 0 {
           42  +		return true
           43  +	}
           44  +	aVal := reflect.ValueOf(a).Pointer()
           45  +	bVal := reflect.ValueOf(b).Pointer()
           46  +	return aVal == bVal
           47  +}
           48  +
           49  +func eq(a, b stackEntry) bool {
           50  +
           51  +	if a.Type() != b.Type() {
           52  +		return false
           53  +	}
           54  +	// Otherwise, the types are the same and we can compare them
           55  +	switch a.Type() {
           56  +	case "Boolean":
           57  +		return a.(Boolean) == b.(Boolean)
           58  +	case "String":
           59  +		return a.String() == b.String()
           60  +	case "Integer":
           61  +		return a.(Integer) == b.(Integer)
           62  +	case "Double":
           63  +		return a.(Double) == b.(Double)
           64  +	case "Symbol":
           65  +		return a.(Symbol) == b.(Symbol)
           66  +	case "Vector":
           67  +		return arrayRefEq(a.(Array), b.(Array))
           68  +	case "Dictionary":
           69  +		return mapRefEq(a.(Dict), b.(Dict))
           70  +	case "Quotation":
           71  +		return &a == &b
           72  +	case "Go Word":
           73  +		return &a == &b
           74  +	}
           75  +	// If we got here, something
           76  +	panic("eq failed!!!")
           77  +
           78  +}
           79  +
           80  +// Boolean is the PISC wrapper around bools
    18     81   type Boolean bool
           82  +
           83  +// Integer is the PISC wrapper around ints
    19     84   type Integer int
           85  +
           86  +// Double is the PISC wrapper aroudn float64
    20     87   type Double float64
           88  +
           89  +// Dict is the wrapper around dictionaries.
           90  +// TODO: Find a way to support dicts with arbitrary keys, not just strings
    21     91   type Dict map[string]stackEntry
           92  +
           93  +// Array is the wrapper around slices of stackEntry
    22     94   type Array []stackEntry
           95  +
           96  +// String is the PISC wrapper around strings
    23     97   type String string
           98  +
           99  +// Symbol is used for unique symboles
    24    100   type Symbol int64
    25    101   
    26    102   // This is a separate sematic from arrays.
    27    103   type quotation struct {
    28    104   	inner  *codeQuotation
    29    105   	locals Dict
    30    106   }
................................................................................
    36    112   
    37    113   type GoFunc GoWord
    38    114   
    39    115   func (g GoFunc) String() string {
    40    116   	return "<Native Code>"
    41    117   }
    42    118   
    43         -func (g GoFunc) Type() string {
    44         -	return "Go Word"
    45         -}
    46         -
    47    119   func (s String) String() string {
    48    120   	return string(s)
    49    121   }
    50    122   
    51    123   func (s Symbol) String() string {
    52    124   	return "#" + fmt.Sprint(int(s))
    53    125   }
................................................................................
    89    161   	}
    90    162   
    91    163   }
    92    164   
    93    165   func (a Array) String() string {
    94    166   	return fmt.Sprint([]stackEntry(a))
    95    167   }
          168  +
          169  +func (g GoFunc) Type() string {
          170  +	return "Go Word"
          171  +}
    96    172   
    97    173   func (i Integer) Type() string {
    98    174   	return "Integer"
    99    175   }
   100    176   
   101    177   func (d Double) Type() string {
   102    178   	return "Double"
................................................................................
   119    195   }
   120    196   
   121    197   func (s String) Type() string {
   122    198   	return "String"
   123    199   }
   124    200   
   125    201   func (s Symbol) Type() string {
   126         -	return "ERROR: Symbol observed on stack!"
          202  +	return "Symbol"
   127    203   }
   128    204   
   129    205   func (dict Dict) Length() int {
   130    206   	return len(dict)
   131    207   }
   132    208   
   133    209   func (a Array) Length() int {
   134    210   	return len(a)
   135    211   }
   136    212   
   137    213   func (s String) Length() int {
   138    214   	return len(s)
   139    215   }