WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

Commit 0d775009 authored by Stefan Marr's avatar Stefan Marr
Browse files

Added Array, Symbol, and SymbolTable


Signed-off-by: default avatarStefan Marr <git@stefan-marr.de>
parent 4b64e0b7
class SymbolTable(object): class SymbolTable(object):
pass
\ No newline at end of file def __init__(self):
self._map = {}
def lookup(self, string):
# Lookup the given string in the hash map
return self._map.get(string, None)
def insert(self, symbol):
# Insert the given symbol into the hash map by associating the
# symbol associated string to the symbol itself
self._map[symbol.get_string()] = symbol
from som.interpreter.interpreter import Interpreter from som.interpreter.interpreter import Interpreter
from som.vm.symbol_table import SymbolTable from som.vm.symbol_table import SymbolTable
from som.vmobjects.object import Object from som.vmobjects.object import Object
from som.vmobjects.clazz import Class from som.vmobjects.clazz import Class
from som.vmobjects.array import Array
from som.vmobjects.symbol import Symbol
import os import os
...@@ -169,14 +171,23 @@ class Universe(object): ...@@ -169,14 +171,23 @@ class Universe(object):
system_object = self._new_instance(self._systemClass) system_object = self._new_instance(self._systemClass)
# Put special objects and classes into the dictionary of globals # Put special objects and classes into the dictionary of globals
self.setGlobal(self.symbol_for("nil"), self._nilObject) self.set_global(self.symbol_for("nil"), self._nilObject)
self.setGlobal(self.symbol_for("true"), self._trueObject) self.set_global(self.symbol_for("true"), self._trueObject)
self.setGlobal(self.symbol_for("false"), self._falseObject) self.set_global(self.symbol_for("false"), self._falseObject)
self.setGlobal(self.symbol_for("system"), self._systemObject) self.set_global(self.symbol_for("system"), self._systemObject)
self.setGlobal(self.symbol_for("System"), self._systemClass) self.set_global(self.symbol_for("System"), self._systemClass)
self.setGlobal(self.symbol_for("Block"), self._blockClass) self.set_global(self.symbol_for("Block"), self._blockClass)
return system_object return system_object
def symbol_for(self, string):
# Lookup the symbol in the symbol table
result = self._symbol_table.lookup(string)
if result:
return result
# Create a new symbol and return it
result = self.new_symbol(string)
return result
def new_array_with_length(self, length): def new_array_with_length(self, length):
# Allocate a new array and set its class to be the array class # Allocate a new array and set its class to be the array class
...@@ -222,6 +233,20 @@ class Universe(object): ...@@ -222,6 +233,20 @@ class Universe(object):
# Return the freshly allocated metaclass class # Return the freshly allocated metaclass class
return result return result
def new_symbol(self, string):
# Allocate a new symbol and set its class to be the symbol class
result = Symbol(self._nilObject)
result.set_class(self._symbolClass)
# Put the string into the symbol
result.set_string(string)
# Insert the new symbol into the symbol table
self._symbol_table.insert(result)
# Return the freshly allocated symbol
return result
def new_system_class(self): def new_system_class(self):
# Allocate the new system class # Allocate the new system class
system_class = Class(self) system_class = Class(self)
...@@ -236,7 +261,7 @@ class Universe(object): ...@@ -236,7 +261,7 @@ class Universe(object):
def _initialize_system_class(self, system_class, super_class, name): def _initialize_system_class(self, system_class, super_class, name):
# Initialize the superclass hierarchy # Initialize the superclass hierarchy
if super_class: if super_class:
system_class.setSuperClass(super_class) system_class.set_super_class(super_class)
system_class.get_class().set_super_class(super_class.get_class()) system_class.get_class().set_super_class(super_class.get_class())
else: else:
system_class.get_class().set_super_class(self._classClass) system_class.get_class().set_super_class(self._classClass)
...@@ -252,7 +277,7 @@ class Universe(object): ...@@ -252,7 +277,7 @@ class Universe(object):
# Initialize the name of the system class # Initialize the name of the system class
system_class.set_name(self.symbol_for(name)) system_class.set_name(self.symbol_for(name))
system_class.get_class().setName(self.symbol_for(name + " class")); system_class.get_class().set_name(self.symbol_for(name + " class"))
# Insert the system class into the dictionary of globals # Insert the system class into the dictionary of globals
self.set_global(system_class.get_name(), system_class) self.set_global(system_class.get_name(), system_class)
...@@ -274,3 +299,69 @@ class Universe(object): ...@@ -274,3 +299,69 @@ class Universe(object):
def has_global(self, name): def has_global(self, name):
# Returns if the universe has a value for the global of the given name # Returns if the universe has a value for the global of the given name
return name in self._globals return name in self._globals
def get_block_class(self, number_of_arguments = None):
if not number_of_arguments:
# Get the generic block class
return self._blockClass
# Compute the name of the block class with the given number of
# arguments
name = self.symbol_for("Block" + str(number_of_arguments))
# Lookup the specific block class in the dictionary of globals and
# return it
if self.has_global(name):
return self.get_global(name)
# Get the block class for blocks with the given number of arguments
result = self._loadClass(name, None)
# Add the appropriate value primitive to the block class
result.add_instance_primitive(Block.get_evaluation_primitive(number_of_arguments, self))
# Insert the block class into the dictionary of globals
self.set_global(name, result)
# Return the loaded block class
return result
def load_class(self, name):
# Check if the requested class is already in the dictionary of globals
if self.has_global(name):
return self.get_global(name)
# Load the class
result = self._load_class(name, None)
# Load primitives (if necessary) and return the resulting class
if result and result.has_primitives():
result.load_primitives()
return result
def _load_system_class(self, system_class):
# Load the system class
result = self._load_class(system_class.get_name(), system_class)
# Load primitives if necessary
if result.has_primitives():
result.load_primitives()
def _load_class(self, name, system_class):
# Try loading the class from all different paths
for cpEntry in self._classpath:
try:
# Load the class from a file and return the loaded class
result = SourcecodeCompiler.compile_class(cpEntry, name.getString(), system_class, self)
if self._dump_bytecodes:
Disassembler.dump(result.get_class())
Disassembler.dump(result)
return result
except IOError:
# Continue trying different paths
pass
# The class could not be found.
return None
from som.vmobjects.object import Object
class Array(Object):
def __init__(self, nilObject):
super(Array, self).__init__(nilObject)
# Private array of indexable fields
self._indexable_fields = None
def get_indexable_field(self, index):
# Get the indexable field with the given index
return self._indexable_fields[index]
def set_indexable_field(self, index, value):
# Set the indexable field with the given index to the given value
self._indexable_fields[index] = value
def get_number_of_indexable_fields(self):
# Get the number of indexable fields in this array
return len(self._indexable_fields)
def set_number_of_indexable_fields_and_clear(self, value, nilObject):
# Allocate a new array of indexable fields, initialized with nil
self._indexable_fields = [nilObject] * value
def copy_and_extend_with(self, value, universe):
# Allocate a new array which has one indexable field more than this
# array
result = universe.new_array_with_length(
self.get_number_of_indexable_fields() + 1)
# Copy the indexable fields from this array to the new array
self._copy_indexable_fields_to(result)
# Insert the given object as the last indexable field in the new array
result.set_indexable_field(self.get_number_of_indexable_fields(), value)
# Return the new array
return result
def _copy_indexable_fields_to(self, destination):
# Copy all indexable fields from this array to the destination array
for i in range(self.get_number_of_indexable_fields()):
destination.set_indexable_field(i, self.get_indexable_field(i))
from som.vmobjects.object import Object
class Symbol(Object):
def __init__(self, nilObject):
super(Symbol, self).__init__(nilObject)
self._string = None
self._number_of_signature_arguments = None
def get_string(self):
# Get the string associated to this symbol
return self._string
def set_string(self, value):
# Set the string associated to this symbol
self._string = value
self._determine_number_of_signature_arguments()
def _determine_number_of_signature_arguments(self):
# Check for binary signature
if self.is_binary_signature():
self._number_of_signature_arguments = 2
else:
# Count the colons in the signature string
number_of_colons = 0
# Iterate through every character in the signature string
for c in self._string:
if c == ':':
number_of_colons += 1
# The number of arguments is equal to the number of colons plus one
self._number_of_signature_arguments = number_of_colons + 1
def get_number_of_signature_arguments(self):
return self._number_of_signature_arguments
def is_binary_signature(self):
# Check the individual characters of the string
for c in self._string:
if (c != '~' and c != '&' and c != '|' and c != '*' and c != '/' and
c != '@' and c != '+' and c != '-' and c != '=' and c != '>' and
c != '<' and c != ',' and c != '%' and c != '\\'):
return False
return True
def __str__(self):
return "#" + self._string
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