diff --git a/lib/soml/code/assignment.rb b/lib/soml/code/assignment.rb index 1096d3b..7b7d6f7 100644 --- a/lib/soml/code/assignment.rb +++ b/lib/soml/code/assignment.rb @@ -2,4 +2,9 @@ module Soml class Assignment < Statement attr_accessor :name , :value end + + class FieldDef < Statement + attr_accessor :name , :type , :value + end + end diff --git a/lib/soml/code/basic_values.rb b/lib/soml/code/basic_values.rb index 38b6854..bac0f89 100644 --- a/lib/soml/code/basic_values.rb +++ b/lib/soml/code/basic_values.rb @@ -25,6 +25,7 @@ module Soml end class NameExpression < Expression attr_accessor :value + alias :name :value def initialize(value) @value = value end diff --git a/lib/soml/code/class_statement.rb b/lib/soml/code/class_statement.rb new file mode 100644 index 0000000..5a74970 --- /dev/null +++ b/lib/soml/code/class_statement.rb @@ -0,0 +1,9 @@ +module Soml + class ClassStatement < Statement + attr_accessor :name , :derives , :statements + end + + class ClassField < Statement + attr_accessor :name , :type + end +end diff --git a/lib/soml/code/code.rb b/lib/soml/code/code.rb index e5201d1..542abdd 100644 --- a/lib/soml/code/code.rb +++ b/lib/soml/code/code.rb @@ -22,4 +22,6 @@ require_relative "field_access" require_relative "call_site" require_relative "basic_values" require_relative "assignment" +require_relative "class_statement" +require_relative "function_statement" require_relative "to_code" diff --git a/lib/soml/code/function_statement.rb b/lib/soml/code/function_statement.rb new file mode 100644 index 0000000..3ac3bf0 --- /dev/null +++ b/lib/soml/code/function_statement.rb @@ -0,0 +1,5 @@ +module Soml + class FunctionStatement < Statement + attr_accessor :return_type , :name , :parameters, :statements , :receiver + end +end diff --git a/lib/soml/code/to_code.rb b/lib/soml/code/to_code.rb index 3989c24..b19a911 100644 --- a/lib/soml/code/to_code.rb +++ b/lib/soml/code/to_code.rb @@ -7,12 +7,55 @@ module Soml class ToCode < AST::Processor + def handler_missing node + raise "No handler on_#{node.type}(node)" + end + + def on_class statement + name , derives , statements = *statement + w = ClassStatement.new() + w.name = name + w.derives = derives.children.first + w.statements = process_all(statements) + w + end + + def on_function statement + return_type , name , parameters, statements , receiver = *statement + w = FunctionStatement.new() + w.return_type = return_type + w.name = name.children.first + w.parameters = parameters.to_a.collect do |p| + raise "error, argument must be a identifier, not #{p}" unless p.type == :parameter + p.children + end + w.statements = process_all(statements) + w.receiver = receiver + w + end + + def on_field_def statement + type , name , value = *statement + w = FieldDef.new() + w.type = type + w.name = process(name) + w.value = process(value) if value + w + end + + def on_class_field statement + type , name = *statement + w = ClassField.new() + w.type = type + w.name = name + w + end + def on_while_statement statement - #puts statement.inspect branch_type , condition , statements = *statement w = WhileStatement.new() w.branch_type = branch_type - w.condition = process(condition) #.first + w.condition = process(condition) w.statements = process_all(statements) w end @@ -21,12 +64,20 @@ module Soml branch_type , condition , if_true , if_false = *statement w = IfStatement.new() w.branch_type = branch_type - w.condition = process(condition) #.first + w.condition = process(condition) w.if_true = process_all(if_true) w.if_false = process_all(if_false) w end + def process_first code + raise "Too many children #{code.inspect}" if code.children.length != 1 + process code.children.first + end + alias :on_conditional :process_first + alias :on_condition :process_first + alias :on_field :process_first + def on_statements statement w = Statements.new() w.statements = process_all(statement.children) @@ -64,7 +115,7 @@ module Soml name_s , arguments , receiver = *statement w = CallSite.new() w.name = name_s - w.arguments = process(arguments) + w.arguments = process_all(arguments) w.receiver = process(receiver) w end