Commits

Nick Meharry committed bd2b403

Added (, ), <, >, ?, and, or, xor, if operators.

Comments (0)

Files changed (29)

     if a.type is b.type is INT:
         return [GObject(a.value + b.value, INT)]
     elif a.type is STR and b.type is BLOCK:
-        b.value.insert(0, a.value)
+        b.value = a.value + ' ' + b.value
         return [b]
     elif a.type is BLOCK and b.type is STR:
-        a.value.insert(0, b.value)
+        a.value = b.value + ' ' + a.value
         return [a]
     elif a.type is b.type and a.type in (ARRAY, STR):
         return [GObject(b.value + a.value, a.type)]
     # as well as collecting all the intermediaries in an array.
     bucket = GObject([], ARRAY)
     while True:
-        stack.push(stack.peek())
-        stack.eval(' '.join(str(x) for x in b.value), stack)
+        stack.push(stack.peek()) # Duplicate
+        stack.eval(b.value, stack)
         if stack.pop().value:
             bucket.value.append(stack.peek())
         else:
             stack.pop()
             break
-        stack.eval(' '.join(str(x) for x in a.value), stack)
+        stack.eval(a.value, stack)
     return [stack.pop(), bucket]
 Slash.run_BLOCK_BLOCK = run_BLOCK_BLOCK
 def run_BLOCK_ARRAY(stack, a, b):
     for item in b.value:
         s = Stack()
         s.push(item)
-        s.eval(' '.join(str(x) for x in a.value), s)
+        s.eval(a.value, s)
         while s.size():
             result.append(s.pop())
     return result
     for item in b.value:
         s = Stack()
         s.push(item)
-        stack.eval(' '.join(str(x) for x in a.value), s)
+        stack.eval(a.value, s)
         while s.size():
             result.value.append(s.pop())
     return [result]
 Semicolon.run_ANY = run_ANY
 vars[';'] = Semicolon
 del Semicolon, run_ANY
+
 #------------------------------------------------------------------------------
 
 #------------------------------------------------------------------------------
 
-LessThan = GFunc(2, ((INT, INT),))
-def run_INT_INT(stack, a, b):
+LessThan = GFunc(2, ((INT, INT), (STR, STR), (ARRAY, ARRAY), (BLOCK, BLOCK),
+                     (INT, STR), (INT, ARRAY), (INT, BLOCK)))
+def run_same(stack, a, b):
     return [GObject(int(b.value < a.value), INT)]
-LessThan.run_INT_INT = run_INT_INT
+LessThan.run_INT_INT = run_same
+LessThan.run_STR_STR = run_same
+LessThan.run_ARRAY_ARRAY = run_same
+LessThan.run_BLOCK_BLOCK = run_same
+def run_INT_iterable(stack, a, b):
+    b.value = b.value[:a.value:]
+    return [b]
+LessThan.run_INT_STR = run_INT_iterable
+LessThan.run_INT_ARRAY = run_INT_iterable
+LessThan.run_INT_BLOCK = run_INT_iterable
 vars['<'] = LessThan
+del LessThan, run_same, run_INT_iterable
 
+#------------------------------------------------------------------------------
 
-del LessThan, run_INT_INT
+GreaterThan = GFunc(2, ((INT, INT), (STR, STR), (ARRAY, ARRAY), (BLOCK, BLOCK),
+                     (INT, STR), (INT, ARRAY), (INT, BLOCK)))
+def run_same(stack, a, b):
+    return [GObject(int(b.value > a.value), INT)]
+GreaterThan.run_INT_INT = run_same
+GreaterThan.run_STR_STR = run_same
+GreaterThan.run_ARRAY_ARRAY = run_same
+GreaterThan.run_BLOCK_BLOCK = run_same
+def run_INT_iterable(stack, a, b):
+    b.value = b.value[a.value::]
+    return [b]
+GreaterThan.run_INT_STR = run_INT_iterable
+GreaterThan.run_INT_ARRAY = run_INT_iterable
+GreaterThan.run_INT_BLOCK = run_INT_iterable
+vars['>'] = GreaterThan
+del GreaterThan, run_same, run_INT_iterable
+
+#------------------------------------------------------------------------------
+
+Equals = GFunc(2, ((INT, INT), (STR, STR), (ARRAY, ARRAY), (BLOCK, BLOCK),
+                     (INT, STR), (INT, ARRAY), (INT, BLOCK)))
+def run_same(stack, a, b):
+    return [GObject(int(b.value == a.value), INT)]
+Equals.run_INT_INT = run_same
+Equals.run_STR_STR = run_same
+Equals.run_ARRAY_ARRAY = run_same
+Equals.run_BLOCK_BLOCK = run_same
+def run_INT_ARRAY(stack, a, b):
+    return [b.value[a.value]]
+def run_INT_STR(stack, a, b):
+    return [GObject(ord(b.value[a.value]), INT)]
+Equals.run_INT_ARRAY = run_INT_ARRAY
+Equals.run_INT_STR = run_INT_STR
+Equals.run_INT_BLOCK = run_INT_STR
+vars['='] = Equals
+del Equals, run_same, run_INT_ARRAY, run_INT_STR
 
 #------------------------------------------------------------------------------
 
     trues = []
     for item in b.value:
         stack.push(item)
-        stack.eval(' '.join(str(x) for x in a.value), stack)
+        stack.eval(a.value, stack)
         if stack.pop().value:
             trues.append(item)
     return [GObject(trues, ARRAY)]
 vars['.'] = Dot
 del Dot, run_ANY
 
+#------------------------------------------------------------------------------
+
+Question = GFunc(2, ((INT, INT), (ARRAY, INT), (INT, ARRAY), (BLOCK, ARRAY)))
+def run_INT_INT(stack, a, b):
+    return [GObject(b.value ** a.value, INT)]
+Question.run_INT_INT = run_INT_INT
+def run_ARRAY_INT(stack, a, b):
+    position = -1
+    for i, item in enumerate(a.value):
+        if item == b:
+            position = i
+            break
+    return [GObject(position, INT)]
+Question.run_ARRAY_INT = run_ARRAY_INT
+def run_INT_ARRAY(stack, a, b):
+    return run_ARRAY_INT(stack, b, a)
+Question.run_INT_ARRAY = run_INT_ARRAY
+def run_BLOCK_ARRAY(stack, a, b):
+    for item in b.value:
+        stack.push(item)
+        stack.eval(a.value, stack)
+        if stack.pop().value:
+            return [item]
+Question.run_BLOCK_ARRAY = run_BLOCK_ARRAY
+vars['?'] = Question
+del Question, run_INT_INT, run_ARRAY_INT, run_INT_ARRAY
+
+#------------------------------------------------------------------------------
+
+OpenParen = GFunc(1, ((INT,), (ARRAY,)))
+def run_INT(stack, a):
+    a.value -= 1
+    return [a]
+OpenParen.run_INT = run_INT
+def run_ARRAY(stack, a):
+    value = a.value.pop(0)
+    return [a, value]
+OpenParen.run_ARRAY = run_ARRAY
+vars['('] = OpenParen
+del OpenParen, run_INT, run_ARRAY
+
+#------------------------------------------------------------------------------
+
+CloseParen = GFunc(1, ((INT,), (ARRAY,)))
+def run_INT(stack, a):
+    a.value += 1
+    return [a]
+CloseParen.run_INT = run_INT
+def run_ARRAY(stack, a):
+    value = a.value.pop()
+    return [a, value]
+CloseParen.run_ARRAY = run_ARRAY
+vars[')'] = CloseParen
+del CloseParen, run_INT, run_ARRAY
+
+#------------------------------------------------------------------------------
+
+If = GFunc(3, ((ANY, ANY, ANY),))
+def run(stack, a, b, c):
+    if c.type is BLOCK:
+        stack.eval(c.value, stack)
+        result = stack.pop()
+    else:
+        result = c
+    
+    if result.value:
+        if b.type is BLOCK:
+            stack.eval(b.value, stack)
+            return []
+        else:
+            return [b]
+    else:
+        if a.type is BLOCK:
+            stack.eval(a.value, stack)
+            return []
+        else:
+            return [a]
+If.run_ANY_ANY_ANY = run
+vars['if'] = If
+del If, run
+
+#------------------------------------------------------------------------------
+
+And = GFunc(0, ())
+def run(stack):
+    stack.eval('1$if', stack)
+    return []
+And.run = run
+vars['and'] = And
+del And, run
+
+#------------------------------------------------------------------------------
+
+Or = GFunc(0, ())
+def run(stack):
+    stack.eval('1$\if', stack)
+    return []
+Or.run = run
+vars['or'] = Or
+del Or, run
+
+#------------------------------------------------------------------------------
+
+XOr = GFunc(1, ((ANY, ANY),))
+def run(stack, a, b):
+    pass
+XOr.run = run
+vars['xor'] = XOr
+del XOr, run
+
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+
+
 __all__ = ('vars',)
             while pc < end:
                 ts.append(tokens[pc])
                 pc += 1
-            stack.push(ts[1:], BLOCK)
-            #print 'Found a block:', stack.peek()
+            stack.push(''.join(ts[1:]), BLOCK)
         elif token == '}':
             pass
         elif token == '[':
         elif self.type is ARRAY:
             return '[%s]' % ' '.join(str(x) for x in self.value)
         elif self.type is BLOCK:
-            return '{%s}' % ' '.join(str(x) for x in self.value)
+            return '{%s}' % self.value
         else:
             return str(self.value)
     __repr__ = __str__
     def __repr__(self):
         return '<GFunc: args=%s, types=%s>' % (self.argCounts, self.argTypes)
     def __call__(self, stack):
+        if self.argCounts == (0,):
+            return self.run(stack)
         for c in self.argCounts:
             # Args is a list of the top of the stack, with order [top, next, ...]
             args = [stack[x] for x in xrange(c)]
 def test(files):
     columns = int(os.popen('stty size', 'r').read().split()[1])
     first = True
+    stderr = sys.stderr
+    passed = 0
+    failed = 0
     for f in files:
         lines = open(f, 'r').read().splitlines()
         try:
             expected = lines[-1]
         except IndexError:
             continue
-        print '  Program: %r' % program
         try:
             result = str(mainloop(program))
             exception = None
             tb = traceback.format_exc()
             exception = e
         
-        sys.stderr.write(chr(27) + '[1m' + f + chr(27) + '[0m' + '.'*(columns-7-len(f)))
         if result != expected:
-            #print '-' * columns
-            sys.stderr.write(chr(27) + '[31m') # Red
-            sys.stderr.write('[FAIL]\n')
-            sys.stderr.write(chr(27) + '[0m')
-            sys.stderr.write('  Program: %r\n' % program)
-            sys.stderr.write('  Expected: %s\n' % expected)
+            failed += 1
+            stderr.write(chr(27) + '[1m' + f + chr(27) + '[0m' + '.'*(columns-7-len(f)))
+            stderr.write(chr(27) + '[31m') # Red
+            stderr.write('[FAIL]\n')
+            stderr.write(chr(27) + '[0m')
+            stderr.write('  Program: %r\n' % program)
+            stderr.write('  Expected: %s\n' % expected)
             if exception:
-                sys.stderr.write(chr(27)+'[31m'+tb+chr(27)+'[0m')
-                #sys.stderr.write(chr(27)+'[31m'+chr(27)+'[1m  Exception: %s%s[0m\n' % (exception, chr(27)))
+                stderr.write(chr(27)+'[31m'+tb+chr(27)+'[0m')
+                #stderr.write(chr(27)+'[31m'+chr(27)+'[1m  Exception: %s%s[0m\n' % (exception, chr(27)))
             else:
-                sys.stderr.write('  Result:   %s\n' % result)
+                stderr.write('  Result:   %s\n' % result)
         else:
-            sys.stderr.write(chr(27) + '[32m') # Green
-            sys.stderr.write('[PASS]\n')
-            sys.stderr.write(chr(27) + '[0m')
-            #sys.stderr.write('  Program: %r\n' % program)
-            #sys.stderr.write('  Expected: %s\n' % expected)
-        
+            passed += 1
+            #stderr.write(chr(27) + '[1m' + f + chr(27) + '[0m' + '.'*(columns-7-len(f)))
+            #stderr.write(chr(27) + '[32m') # Green
+            #stderr.write('[PASS]\n')
+            #stderr.write(chr(27) + '[0m')
+    bold = chr(27) + '[1m'
+    reset = chr(27) + '[0m'
+    stderr.write('%s%i%s test%s passed, %s%i%s test%s failed\n' % (
+        bold, passed, reset, 's' if passed != 1 else '',
+        bold, failed, reset, 's' if failed != 1 else ''))
 
 if __name__ == '__main__':
     if len(sys.argv) == 1:
+5 {1 1+} and
+2

tests/closeparen1.gs

+5)
+6

tests/closeparen2.gs

+[1 2 3])
+[1 2] 3
+3 4 =
+0
+"asdf" "asdg" =
+0
+[1 2 3] 2 =
+3
+{asdf} -1 =
+102

tests/greaterthan1.gs

+3 4 >
+0

tests/greaterthan2.gs

+"asdf" "asdg" >
+0

tests/greaterthan3.gs

+[1 2 3] 2 >
+[3]

tests/greaterthan4.gs

+{asdf} -1 >
+{f}
+1 2 3 if
+2
+0 2 {1.} if
+1 1

tests/lessthan1.gs

+3 4 <
+1

tests/lessthan2.gs

+"asdf" "asdg" <
+1

tests/lessthan3.gs

+[1 2 3] 2 <
+[1 2]

tests/lessthan4.gs

+{asdf} -1 <
+{asd}

tests/openparen1.gs

+5(
+4

tests/openparen2.gs

+[1 2 3](
+[2 3] 1
+5 {1 0/} or
+5

tests/question1.gs

+2 8?
+256

tests/question2.gs

+5 [4 3 5 1] ?
+2

tests/question3.gs

+[1 2 3 4 5 6] {.* 20>} ?
+5
+0 [3] xor
+[3]
+2 [3] xor
+0