2017-04-08 12:09:25 +03:00
|
|
|
#
|
2019-10-04 00:36:49 +03:00
|
|
|
# SOL -- Simple Object Language
|
|
|
|
#
|
|
|
|
# SOL is the abstraction of ruby: ruby minus the fluff
|
2017-04-08 12:09:25 +03:00
|
|
|
# fluff is generally what makes ruby nice to use, like 3 ways to achieve the same thing
|
|
|
|
# if/unless/ternary , reverse ifs (ie statement if condition), reverse whiles,
|
|
|
|
# implicit blocks, splats and multiple assigns etc
|
|
|
|
#
|
2019-10-04 00:36:49 +03:00
|
|
|
# Sol has expression and statements, revealing that age old dichotomy of code and
|
2019-08-19 11:33:12 +03:00
|
|
|
# data. Statements represent code whereas Expressions resolve to data.
|
|
|
|
# (in ruby there are no pure statements, everthing resolves to data)
|
2019-09-24 15:44:33 +03:00
|
|
|
#
|
2019-10-04 00:36:49 +03:00
|
|
|
# Sol resolves to SlotMachine in the next step down. But it also the place where we create
|
2019-09-24 15:44:33 +03:00
|
|
|
# Parfait representations for the main oo players, ie classes and methods.
|
|
|
|
# The protocol is thus two stage:
|
|
|
|
# - first to_parfait with implicit side-effects of creating parfait objects that
|
|
|
|
# are added to the Parfait object_space
|
2019-10-03 21:07:55 +03:00
|
|
|
# - second to_slot , which will return a slot version of the statement. This may be code
|
2019-09-24 15:44:33 +03:00
|
|
|
# or a compiler (for methods), or compiler collection (for classes)
|
|
|
|
#
|
2019-10-04 00:36:49 +03:00
|
|
|
module Sol
|
2017-04-08 12:09:25 +03:00
|
|
|
|
|
|
|
# Base class for all statements in the tree. Derived classes correspond to known language
|
|
|
|
# constructs
|
|
|
|
#
|
2019-08-19 11:33:12 +03:00
|
|
|
# Basically Statements represent code, generally speaking code "does things".
|
2019-10-04 00:36:49 +03:00
|
|
|
# But Sol distinguishes Expressions (see below), that represent data, and as such
|
2019-08-19 11:33:12 +03:00
|
|
|
# don't do things themselves, rather passively participate in being pushed around
|
2017-04-08 12:09:25 +03:00
|
|
|
class Statement
|
|
|
|
|
2019-09-24 15:44:33 +03:00
|
|
|
# Create any neccessary parfait object and add them to the parfait object_space
|
|
|
|
# return the object for testing
|
|
|
|
#
|
|
|
|
# Default implementation (ie this one) riases to show errors
|
|
|
|
# argument is general and depends on caller
|
|
|
|
def to_parfait(arg)
|
|
|
|
raise "Called when it shouldn't #{self.class}"
|
|
|
|
end
|
|
|
|
|
2019-10-03 21:07:55 +03:00
|
|
|
# create slot_machine version of the statement, this is often code, that is added
|
|
|
|
# to the compiler, but for methods it is a compiler and for classes a collection of those.
|
2019-09-24 15:44:33 +03:00
|
|
|
#
|
|
|
|
# The argument given most often is a compiler
|
|
|
|
# The default implementation (this) is to raise an error
|
2019-10-03 20:55:41 +03:00
|
|
|
def to_slot( _ )
|
2017-04-12 11:52:23 +03:00
|
|
|
raise "Not implemented for #{self}"
|
|
|
|
end
|
|
|
|
|
2019-09-19 20:48:21 +03:00
|
|
|
def at_depth(depth , lines)
|
2018-07-03 22:18:19 +03:00
|
|
|
prefix = " " * 2 * depth
|
2019-09-19 20:48:21 +03:00
|
|
|
strings = lines.split("\n")
|
2018-07-03 22:18:19 +03:00
|
|
|
strings.collect{|str| prefix + str}.join("\n")
|
|
|
|
end
|
|
|
|
|
2018-03-15 12:46:56 +05:30
|
|
|
end
|
2017-04-08 12:09:25 +03:00
|
|
|
|
2019-08-19 11:33:12 +03:00
|
|
|
# An Expression is a Statement that represents data. ie variables constants
|
|
|
|
# (see basic_values) , but alos classes, methods and lambdas
|
|
|
|
class Expression < Statement
|
|
|
|
|
|
|
|
def each(&block)
|
|
|
|
block.call(self)
|
|
|
|
end
|
2017-04-08 17:22:53 +03:00
|
|
|
|
2018-03-16 10:32:11 +05:30
|
|
|
def ct_type
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
2018-03-15 12:46:56 +05:30
|
|
|
def normalize
|
|
|
|
raise "should not be normalized #{self}"
|
2017-04-08 17:22:53 +03:00
|
|
|
end
|
2018-03-15 20:33:38 +05:30
|
|
|
|
2019-08-19 11:33:12 +03:00
|
|
|
# for loading into a slot, return the "slot_definition" that can be passed to
|
2018-03-15 20:33:38 +05:30
|
|
|
# SlotLoad.
|
2019-08-19 11:33:12 +03:00
|
|
|
def to_slot(compiler)
|
2018-03-15 20:33:38 +05:30
|
|
|
raise "not iplemented in #{self}"
|
|
|
|
end
|
2018-03-15 11:24:14 +05:30
|
|
|
|
|
|
|
end
|
|
|
|
|
2017-04-08 12:09:25 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2018-07-20 14:22:26 +03:00
|
|
|
require_relative "assignment"
|
2018-06-29 22:46:00 +03:00
|
|
|
require_relative "basic_values"
|
2018-07-30 14:45:37 +03:00
|
|
|
require_relative "call_statement"
|
2019-08-19 11:33:12 +03:00
|
|
|
require_relative "class_expression"
|
2018-06-29 22:46:00 +03:00
|
|
|
require_relative "if_statement"
|
2018-07-20 14:22:26 +03:00
|
|
|
require_relative "ivar_assignment"
|
2019-08-19 11:33:12 +03:00
|
|
|
require_relative "lambda_expression"
|
2018-06-29 22:46:00 +03:00
|
|
|
require_relative "local_assignment"
|
2019-08-25 14:40:59 +03:00
|
|
|
require_relative "macro_expression"
|
2019-08-19 11:33:12 +03:00
|
|
|
require_relative "method_expression"
|
|
|
|
require_relative "class_method_expression"
|
2018-06-29 22:46:00 +03:00
|
|
|
require_relative "return_statement"
|
|
|
|
require_relative "statements"
|
|
|
|
require_relative "send_statement"
|
2019-08-19 18:48:13 +03:00
|
|
|
require_relative "super_statement"
|
2018-06-29 22:46:00 +03:00
|
|
|
require_relative "variables"
|
|
|
|
require_relative "while_statement"
|
|
|
|
require_relative "yield_statement"
|