Commit a073dd36 authored by Stefan Marr's avatar Stefan Marr

Refactoring class methods to module methods

- RPython does not support them, so we changed from the to module-level methods
Signed-off-by: default avatarStefan Marr <git@stefan-marr.de>
parent eb5bce49
from som.vm.universe import Universe
from som.interpreter.bytecodes import Bytecodes
from som.vm.universe import error_print, error_println, Universe
from som.interpreter.bytecodes import bytecode_as_str, bytecode_length, Bytecodes
class Disassembler(object):
def dump(clazz):
for i in range(0, clazz.get_number_of_instance_invokables()):
inv = clazz.get_instance_invokable(i)
@classmethod
def dump(cls, clazz):
for i in range(0, clazz.get_number_of_instance_invokables()):
inv = clazz.get_instance_invokable(i)
# output header and skip if the Invokable is a Primitive
error_print(str(clazz.get_name()) + ">>" +
str(inv.get_signature()) + " = ")
# output header and skip if the Invokable is a Primitive
Universe.error_print(str(clazz.get_name()) + ">>" +
str(inv.get_signature()) + " = ")
if inv.is_primitive():
error_println("<primitive>")
continue
# output actual method
dump_method(inv, "\t")
if inv.is_primitive():
Universe.error_println("<primitive>")
continue
# output actual method
cls.dump_method(inv, "\t")
def dump_method(m, indent):
error_println("(")
@classmethod
def dump_method(cls, m, indent):
Universe.error_println("(")
# output stack information
error_println("%s<%d locals, %d stack, %d bc_count>" % (indent,
m.get_number_of_locals().get_embedded_integer(),
m.get_maximum_number_of_stack_elements().get_embedded_integer(),
m.get_number_of_bytecodes()))
# output stack information
Universe.error_println("%s<%d locals, %d stack, %d bc_count>" % (indent,
m.get_number_of_locals().get_embedded_integer(),
m.get_maximum_number_of_stack_elements().get_embedded_integer(),
m.get_number_of_bytecodes()))
# output bytecodes
b = 0
while b < m.get_number_of_bytecodes():
error_print(indent)
# bytecode index
if b < 10: error_print(" ")
if b < 100: error_print(" ")
error_print(" %d:" % b)
# output bytecodes
b = 0
while b < m.get_number_of_bytecodes():
Universe.error_print(indent)
# bytecode index
if b < 10: Universe.error_print(" ")
if b < 100: Universe.error_print(" ")
Universe.error_print(" %d:" % b)
# mnemonic
bytecode = m.get_bytecode(b)
error_print(bytecode_as_str(bytecode) + " ")
# mnemonic
bytecode = m.get_bytecode(b)
Universe.error_print(Bytecodes.as_str(bytecode) + " ")
# parameters (if any)
if bytecode_length(bytecode) == 1:
error_println()
b += 1
continue
if bytecode == Bytecodes.push_local:
error_println("local: " + str(m.get_bytecode(b + 1)) +
", context: " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.push_argument:
error_println("argument: " + str(m.get_bytecode(b + 1)) +
", context " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.push_field:
error_println("(index: " + str(m.get_bytecode(b + 1)) +
") field: " + str(m.get_holder().get_instance_field_name(m.get_bytecode(b + 1))))
elif bytecode == Bytecodes.push_block:
error_print("block: (index: " + str(m.get_bytecode(b + 1)) + ") ")
dump_method(m.get_constant(b), indent + "\t")
elif bytecode == Bytecodes.push_constant:
constant = m.get_constant(b)
error_println("(index: " + str(m.get_bytecode(b + 1)) +
") value: (" +
str(constant.get_class().get_name()) +
") " + str(constant))
elif bytecode == Bytecodes.push_global:
error_println("(index: " + str(m.get_bytecode(b + 1)) +
") value: " + str(m.get_constant(b)))
elif bytecode == Bytecodes.pop_local:
error_println("local: " + str(m.get_bytecode(b + 1)) +
", context: " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.pop_argument:
error_println("argument: " + str(m.get_bytecode(b + 1)) +
", context: " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.pop_field:
error_println("(index: " + str(m.get_bytecode(b + 1)) +
") field: " + str(m.get_holder().get_instance_field_name(m.get_bytecode(b + 1))))
elif bytecode == Bytecodes.send:
error_println("(index: " + str(m.get_bytecode(b + 1)) +
") signature: " + str(m.get_constant(b)))
elif bytecode == Bytecodes.super_send:
error_println("(index: " + str(m.get_bytecode(b + 1)) +
") signature: " + str(m.get_constant(b)))
else:
error_println("<incorrect bytecode>")
b += bytecode_length(m.get_bytecode(b))
# parameters (if any)
if Bytecodes.get_bytecode_length(bytecode) == 1:
Universe.error_println()
b += 1
continue
if bytecode == Bytecodes.push_local:
Universe.error_println("local: " + str(m.get_bytecode(b + 1)) +
", context: " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.push_argument:
Universe.error_println("argument: " + str(m.get_bytecode(b + 1)) +
", context " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.push_field:
Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) +
") field: " + str(m.get_holder().get_instance_field_name(m.get_bytecode(b + 1))))
elif bytecode == Bytecodes.push_block:
Universe.error_print("block: (index: " + str(m.get_bytecode(b + 1)) + ") ")
cls.dump_method(m.get_constant(b), indent + "\t")
elif bytecode == Bytecodes.push_constant:
constant = m.get_constant(b)
Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) +
") value: (" +
str(constant.get_class().get_name()) +
") " + str(constant))
elif bytecode == Bytecodes.push_global:
Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) +
") value: " + str(m.get_constant(b)))
elif bytecode == Bytecodes.pop_local:
Universe.error_println("local: " + str(m.get_bytecode(b + 1)) +
", context: " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.pop_argument:
Universe.error_println("argument: " + str(m.get_bytecode(b + 1)) +
", context: " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.pop_field:
Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) +
") field: " + str(m.get_holder().get_instance_field_name(m.get_bytecode(b + 1))))
elif bytecode == Bytecodes.send:
Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) +
") signature: " + str(m.get_constant(b)))
elif bytecode == Bytecodes.super_send:
Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) +
") signature: " + str(m.get_constant(b)))
else:
Universe.error_println("<incorrect bytecode>")
b += Bytecodes.get_bytecode_length(m.get_bytecode(b))
Universe.error_println(indent + ")")
error_println(indent + ")")
from som.interpreter.bytecodes import Bytecodes as BC
from som.vmobjects.primitive import Primitive
from som.interpreter.bytecodes import bytecode_length, bytecode_stack_effect, bytecode_stack_effect_depends_on_send, Bytecodes as BC
from som.vmobjects.primitive import Primitive, empty_primitive
class MethodGenerationContext(object):
......@@ -26,7 +26,7 @@ class MethodGenerationContext(object):
return self._primitive
def assemble_primitive(self, universe):
return Primitive.get_empty_primitive(self._signature.get_string(), universe)
return empty_primitive(self._signature.get_string(), universe)
def assemble(self, universe):
# create a method instance with the given number of bytecodes and literals
......@@ -63,13 +63,13 @@ class MethodGenerationContext(object):
while i < len(self._bytecode):
bc = self._bytecode[i]
if BC.stack_effect_depends_on_send(bc):
if bytecode_stack_effect_depends_on_send(bc):
signature = self._literals[self._bytecode[i + 1]]
depth += BC.get_stack_effect(bc, signature.get_number_of_signature_arguments())
depth += bytecode_stack_effect(bc, signature.get_number_of_signature_arguments())
else:
depth += BC.get_stack_effect(bc)
depth += bytecode_stack_effect(bc)
i += BC.get_bytecode_length(bc)
i += bytecode_length(bc)
if depth > max_depth:
max_depth = depth
......
from som.compiler.symbol import Symbol
from som.compiler.symbol import Symbol, symbol_as_str
from som.compiler.lexer import Lexer
from som.compiler.bytecode_generator import BytecodeGenerator
from som.compiler.method_generation_context import MethodGenerationContext
from som.vmobjects.integer import Integer
from som.vmobjects.integer import integer_value_fits
class Parser(object):
......@@ -111,7 +111,7 @@ class Parser(object):
return True
err = ("Error: unexpected symbol in line %d. Expected %s, but found %s" %
(self._lexer.get_current_line_number(), Symbol.as_str(s), Symbol.as_str(self._sym)))
(self._lexer.get_current_line_number(), symbol_as_str(s), symbol_as_str(self._sym)))
if self._printable_symbol():
err += " (" + self._text + ")"
err += ": " + self._lexer.get_raw_buffer()
......@@ -121,10 +121,10 @@ class Parser(object):
if self._accept_one_of(symbol_list):
return True
expected = ", ".join([Symbol.as_str(x) for x in symbol_list])
expected = ", ".join([symbol_as_str(x) for x in symbol_list])
err = ("Error: unexpected symbol in line %d. Expected one of %s, but found %s" %
(self._lexer.get_current_line_number(), expected, Symbol.as_str(self._sym)))
(self._lexer.get_current_line_number(), expected, symbol_as_str(self._sym)))
if self._printable_symbol():
err += " (" + self._text + ")"
err += ": " + self._lexer.get_raw_buffer()
......@@ -460,7 +460,7 @@ class Parser(object):
val = self._literal_decimal()
if Integer.value_fits(val):
if integer_value_fits(val):
lit = self._universe.new_integer(val)
else:
lit = self._universe.new_biginteger(val)
......
......@@ -33,9 +33,9 @@ class Symbol(object):
KeywordSequence = 29
OperatorSequence = 30
@classmethod
def as_str(cls, symbol):
for key, val in cls.__dict__:
if val == symbol:
return key
raise ValueError('No Symbol defined for the value %d.' % symbol)
def symbol_as_str(symbol):
for key, val in Symbol.__dict__:
if val == symbol:
return key
raise ValueError('No Symbol defined for the value %d.' % symbol)
......@@ -56,28 +56,28 @@ class Bytecodes(object):
return_local : 0,
return_non_local : 0 }
@classmethod
def get_bytecode_length(cls, bytecode):
return cls._bytecode_length[bytecode]
@classmethod
def get_stack_effect(cls, bytecode, number_of_arguments_of_message_send = 0):
if cls.stack_effect_depends_on_send(bytecode):
return -number_of_arguments_of_message_send + 1 # +1 in order to account for the return value
else:
return cls._bytecode_stack_effect[bytecode]
@classmethod
def stack_effect_depends_on_send(cls, bytecode):
return cls._bytecode_stack_effect[bytecode] is cls._stack_effect_depends_on_message
def bytecode_length(bytecode):
return Bytecodes._bytecode_length[bytecode]
def bytecode_stack_effect(bytecode, number_of_arguments_of_message_send = 0):
if bytecode_stack_effect_depends_on_send(bytecode):
return -number_of_arguments_of_message_send + 1 # +1 in order to account for the return value
else:
return Bytecodes._bytecode_stack_effect[bytecode]
@classmethod
def as_str(cls, bytecode):
if not isinstance(bytecode, int):
raise ValueError('bytecode is expected to be an integer.')
def bytecode_stack_effect_depends_on_send(bytecode):
return Bytecodes._bytecode_stack_effect[bytecode] is Bytecodes._stack_effect_depends_on_message
def bytecode_as_str(bytecode):
if not isinstance(bytecode, int):
raise ValueError('bytecode is expected to be an integer.')
for key, val in Bytecodes.__dict__.iteritems():
if val == bytecode:
return key.upper()
for key, val in cls.__dict__.iteritems():
if val == bytecode:
return key.upper()
raise ValueError('No defined defined for the value %d.' % bytecode)
raise ValueError('No defined defined for the value %d.' % bytecode)
from som.interpreter.bytecodes import Bytecodes
from som.interpreter.bytecodes import bytecode_length
class Interpreter(object):
......@@ -184,10 +184,10 @@ class Interpreter(object):
bytecode = self.get_method().get_bytecode(bytecode_index)
# Get the length of the current bytecode
bytecode_length = Bytecodes.get_bytecode_length(bytecode)
bc_length = bytecode_length(bytecode)
# Compute the next bytecode index
next_bytecode_index = bytecode_index + bytecode_length
next_bytecode_index = bytecode_index + bc_length
# Update the bytecode index of the frame
self.get_frame().set_bytecode_index(next_bytecode_index)
......
from som.primitives.primitives import Primitives
from som.vmobjects.primitive import Primitive
from som.vmobjects.integer import Integer
from som.vmobjects.integer import integer_value_fits
import math
......@@ -24,7 +24,7 @@ class BigIntegerPrimitives(Primitives):
# Do operation and perform conversion to Integer if required
result = left.get_embedded_biginteger() + right_obj.get_embedded_value()
if Integer.value_fits(result):
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
......@@ -36,7 +36,7 @@ class BigIntegerPrimitives(Primitives):
# Do operation and perform conversion to Integer if required
result = left.get_embedded_biginteger() - right_obj.get_embedded_value()
if Integer.value_fits(result):
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
......@@ -48,7 +48,7 @@ class BigIntegerPrimitives(Primitives):
# Do operation and perform conversion to Integer if required
result = left.get_embedded_biginteger() * right_obj.get_embedded_value()
if Integer.value_fits(result):
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
......@@ -60,7 +60,7 @@ class BigIntegerPrimitives(Primitives):
# Do operation and perform conversion to Integer if required
result = left.get_embedded_biginteger() / right_obj.get_embedded_value()
if Integer.value_fits(result):
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
......
from som.primitives.primitives import Primitives
from som.vmobjects.primitive import Primitive
from som.vmobjects.biginteger import BigInteger
from som.vmobjects.integer import Integer
from som.vmobjects.integer import integer_value_fits, Integer
from som.vmobjects.double import Double
import math
......@@ -9,10 +9,9 @@ import random
class IntegerPrimitives(Primitives):
def _push_long_result(self, frame, result):
# Check with integer bounds and push:
if Integer.value_fits(result):
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
......
from som.primitives.primitives import Primitives
from som.vmobjects.primitive import Primitive
from som.vm.universe import std_print, std_println
import time
class SystemPrimitives(Primitives):
......@@ -37,11 +39,11 @@ class SystemPrimitives(Primitives):
def _print_string(ivkbl, frame, interpreter):
argument = frame.pop()
self._universe.std_print(argument.get_embedded_string())
std_print(argument.get_embedded_string())
self._install_instance_primitive(Primitive("printString:", self._universe, _print_string))
def _print_newline(ivkbl, frame, interpreter):
self._universe.std_println()
std_println()
self._install_instance_primitive(Primitive("printNewline", self._universe, _print_newline))
def _time(ivkbl, frame, interpreter):
......
......@@ -10,7 +10,7 @@ from som.vmobjects.symbol import Symbol
from som.vmobjects.method import Method
from som.vmobjects.integer import Integer
from som.vmobjects.string import String
from som.vmobjects.block import Block
from som.vmobjects.block import Block, block_evaluation_primitive
from som.vmobjects.frame import Frame
from som.vmobjects.biginteger import BigInteger
from som.vmobjects.double import Double
......@@ -251,12 +251,12 @@ class Universe(object):
def _print_usage_and_exit(self):
# Print the usage
self.std_println("Usage: som [-options] [args...] ")
self.std_println(" ")
self.std_println("where options include: ")
self.std_println(" -cp <directories separated by " + os.pathsep + ">")
self.std_println(" set search path for application classes")
self.std_println(" -d enable disassembling")
std_println("Usage: som [-options] [args...] ")
std_println(" ")
std_println("where options include: ")
std_println(" -cp <directories separated by " + os.pathsep + ">")
std_println(" set search path for application classes")
std_println(" -d enable disassembling")
# Exit
self.exit(0)
......@@ -586,7 +586,7 @@ class Universe(object):
result = self._load_class(name, None)
# Add the appropriate value primitive to the block class
result.add_instance_primitive(Block.get_evaluation_primitive(number_of_arguments, self))
result.add_instance_primitive(block_evaluation_primitive(number_of_arguments, self))
# Insert the block class into the dictionary of globals
self.set_global(name, result)
......@@ -623,9 +623,9 @@ class Universe(object):
# Load the class from a file and return the loaded class
result = sourcecode_compiler.compile_class_from_file(cpEntry, name.get_string(), system_class, self)
if self._dump_bytecodes:
from som.compiler.disassembler import Disassembler
Disassembler.dump(result.get_class())
Disassembler.dump(result)
from som.compiler.disassembler import dump
dump(result.get_class())
dump(result)
return result
except IOError:
......@@ -639,25 +639,21 @@ class Universe(object):
# Load the class from a stream and return the loaded class
result = sourcecode_compiler.compile_class_from_string(stmt, None, self)
if self._dump_bytecodes:
from som.compiler.disassembler import Disassembler
Disassembler.dump(result)
from som.compiler.disassembler import dump
dump(result)
return result
@classmethod
def error_print(cls, msg):
print(msg, file=sys.stderr, end="")
def error_print(msg):
print(msg, file=sys.stderr, end="")
@classmethod
def error_println(cls, msg = ""):
print(msg, file=sys.stderr)
def error_println(msg = ""):
print(msg, file=sys.stderr)
@classmethod
def std_print(cls, msg):
print(msg, end="")
def std_print(msg):
print(msg, end="")
@classmethod
def std_println(cls, msg=""):
print(msg)
def std_println(msg=""):
print(msg)
def main(args):
u = Universe()
......
......@@ -63,6 +63,5 @@ class Block(Object):
# Return the signature string
return signature_string
@classmethod
def get_evaluation_primitive(cls, num_args, universe):
return cls.Evaluation(num_args, universe)
def block_evaluation_primitive(num_args, universe):
return Block.Evaluation(num_args, universe)
......@@ -19,6 +19,5 @@ class Integer(Object):
def __str__(self):
return str(self._embedded_integer)
@classmethod
def value_fits(cls, value):
return value <= 2147483647 and value > -2147483646
\ No newline at end of file
def integer_value_fits(value):
return value <= 2147483647 and value > -2147483646
......@@ -51,14 +51,14 @@ class Primitive(Object, Invokable):
# By default a primitive is not empty
return False
@classmethod
def get_empty_primitive(cls, signature_string, universe):
# Return an empty primitive with the given signature
def _invoke(ivkbl, frame, interpreter):
# Write a warning to the screen
universe.std_println("Warning: undefined primitive " +
ivkbl.get_signature().get_string() + " called")
# The empty primitives are empty
def _is_empty(self): return True
return Primitive(signature_string, universe, _invoke, _is_empty)
def empty_primitive(signature_string, universe):
# Return an empty primitive with the given signature
def _invoke(ivkbl, frame, interpreter):
# Write a warning to the screen
universe.std_println("Warning: undefined primitive " +
ivkbl.get_signature().get_string() + " called")
# The empty primitives are empty
def _is_empty(self): return True
return Primitive(signature_string, universe, _invoke, _is_empty)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment