1.1 --- a/rsvplib.py Sat Aug 07 02:06:15 2010 +0200
1.2 +++ b/rsvplib.py Mon Aug 09 01:23:05 2010 +0200
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 A native function library for a really simple virtual processor.
1.6
1.7 -Copyright (C) 2007, 2008, 2009 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2007, 2008, 2009, 2010 Paul Boddie <paul@boddie.org.uk>
1.9
1.10 This program is free software; you can redistribute it and/or modify it under
1.11 the terms of the GNU General Public License as published by the Free Software
1.12 @@ -26,16 +26,15 @@
1.13
1.14 "Native function implementations."
1.15
1.16 - def __init__(self, machine, true_constant, false_constant):
1.17 + def __init__(self, machine, constants):
1.18
1.19 """
1.20 - Initialise the library with the 'machine' and the addresses
1.21 - 'true_constant' and 'false_constant'.
1.22 + Initialise the library with the 'machine' and the 'constants' addresses
1.23 + dictionary.
1.24 """
1.25
1.26 self.machine = machine
1.27 - self.true_constant = true_constant
1.28 - self.false_constant = false_constant
1.29 + self.constants = constants
1.30
1.31 # Native class constants.
1.32
1.33 @@ -97,7 +96,7 @@
1.34
1.35 self.machine.result = DataValue(addr, addr)
1.36
1.37 - def builtins_logical_op(self, operand_class, op, true_if_incompatible):
1.38 + def builtins_logical_op(self, operand_class, op):
1.39 frame = self.local_sp_stack[-1]
1.40
1.41 # Get operands addresses.
1.42 @@ -107,14 +106,13 @@
1.43
1.44 # Test operand suitability.
1.45 # NOTE: Handle comparisons of incompatible types more appropriately.
1.46 + # NOTE: Return NotImplemented.
1.47
1.48 if not (self.machine._CheckInstance(left_value.ref, operand_class) and
1.49 self.machine._CheckInstance(right_value.ref, operand_class)):
1.50
1.51 - if true_if_incompatible:
1.52 - self.machine.result = DataValue(self.true_constant, self.true_constant)
1.53 - else:
1.54 - self.machine.result = DataValue(self.false_constant, self.false_constant)
1.55 + notimpl = self.constants[NotImplemented]
1.56 + self.machine.result = DataValue(notimpl, notimpl)
1.57 return
1.58
1.59 # NOTE: Assume single location for data.
1.60 @@ -126,9 +124,9 @@
1.61 # NOTE: The data is considered ready to use.
1.62
1.63 if op(self.machine.load(left_data), self.machine.load(right_data)):
1.64 - self.machine.result = DataValue(self.true_constant, self.true_constant)
1.65 + self.machine.result = DataValue(self.constants[True], self.constants[True])
1.66 else:
1.67 - self.machine.result = DataValue(self.false_constant, self.false_constant)
1.68 + self.machine.result = DataValue(self.constants[False], self.constants[False])
1.69
1.70 # Operators.
1.71 # Although this takes a short-cut by using the operator module, testing is
1.72 @@ -145,40 +143,40 @@
1.73 return self.builtins_int_arithmetic_op(operator.pow)
1.74
1.75 def builtins_int_lt(self):
1.76 - return self.builtins_logical_op(self.int_class, operator.lt, 0)
1.77 + return self.builtins_logical_op(self.int_class, operator.lt)
1.78
1.79 def builtins_int_le(self):
1.80 - return self.builtins_logical_op(self.int_class, operator.le, 0)
1.81 + return self.builtins_logical_op(self.int_class, operator.le)
1.82
1.83 def builtins_int_gt(self):
1.84 - return self.builtins_logical_op(self.int_class, operator.gt, 0)
1.85 + return self.builtins_logical_op(self.int_class, operator.gt)
1.86
1.87 def builtins_int_ge(self):
1.88 - return self.builtins_logical_op(self.int_class, operator.ge, 0)
1.89 + return self.builtins_logical_op(self.int_class, operator.ge)
1.90
1.91 def builtins_int_eq(self):
1.92 - return self.builtins_logical_op(self.int_class, operator.eq, 0)
1.93 + return self.builtins_logical_op(self.int_class, operator.eq)
1.94
1.95 def builtins_int_ne(self):
1.96 - return self.builtins_logical_op(self.int_class, operator.ne, 1)
1.97 + return self.builtins_logical_op(self.int_class, operator.ne)
1.98
1.99 def builtins_str_lt(self):
1.100 - return self.builtins_logical_op(self.str_class, operator.lt, 0)
1.101 + return self.builtins_logical_op(self.str_class, operator.lt)
1.102
1.103 def builtins_str_le(self):
1.104 - return self.builtins_logical_op(self.str_class, operator.le, 0)
1.105 + return self.builtins_logical_op(self.str_class, operator.le)
1.106
1.107 def builtins_str_gt(self):
1.108 - return self.builtins_logical_op(self.str_class, operator.gt, 0)
1.109 + return self.builtins_logical_op(self.str_class, operator.gt)
1.110
1.111 def builtins_str_ge(self):
1.112 - return self.builtins_logical_op(self.str_class, operator.ge, 0)
1.113 + return self.builtins_logical_op(self.str_class, operator.ge)
1.114
1.115 def builtins_str_eq(self):
1.116 - return self.builtins_logical_op(self.str_class, operator.eq, 0)
1.117 + return self.builtins_logical_op(self.str_class, operator.eq)
1.118
1.119 def builtins_str_ne(self):
1.120 - return self.builtins_logical_op(self.str_class, operator.ne, 1)
1.121 + return self.builtins_logical_op(self.str_class, operator.ne)
1.122
1.123 def builtins_int_and(self):
1.124 return self.builtins_int_arithmetic_op(operator.and_)
1.125 @@ -209,9 +207,9 @@
1.126 # NOTE: The data is considered ready to use.
1.127
1.128 if self.machine.load(left_data) != 0:
1.129 - self.machine.result = DataValue(self.true_constant, self.true_constant)
1.130 + self.machine.result = DataValue(self.constants[True], self.constants[True])
1.131 else:
1.132 - self.machine.result = DataValue(self.false_constant, self.false_constant)
1.133 + self.machine.result = DataValue(self.constants[False], self.constants[False])
1.134
1.135 def builtins_int_neg(self):
1.136 frame = self.local_sp_stack[-1]