From 4a9b492dd9fb1d7cbc6f114aee226ff227753568 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Sun, 6 Mar 2016 09:40:41 +0200 Subject: [PATCH] move to typed structure on the way to removing the language, the at needs to be replaced with a typed structure. --- lib/soml-parser.rb | 1 + lib/soml/code/assignment.rb | 5 ++ lib/soml/code/basic_values.rb | 38 ++++++++ lib/soml/code/call_site.rb | 5 ++ lib/soml/code/code.rb | 25 ++++++ lib/soml/code/field_access.rb | 5 ++ lib/soml/code/if_statement.rb | 5 ++ lib/soml/code/operator_expression.rb | 5 ++ lib/soml/code/return_statement.rb | 5 ++ lib/soml/code/statements.rb | 5 ++ lib/soml/code/to_code.rb | 108 +++++++++++++++++++++++ lib/soml/code/while_statement.rb | 5 ++ test/README.md | 8 +- test/cases/array_constant/array_list.tst | 5 -- test/cases/array_constant/array_ops.tst | 10 --- test/cases/array_constant/one_array.tst | 4 - test/cases/hash_constant/hash.tst | 6 -- test/cases/hash_constant/hash2.tst | 6 -- test/cases/hash_constant/hash_list.tst | 9 -- test/test_all.rb | 6 ++ 20 files changed, 223 insertions(+), 43 deletions(-) create mode 100644 lib/soml/code/assignment.rb create mode 100644 lib/soml/code/basic_values.rb create mode 100644 lib/soml/code/call_site.rb create mode 100644 lib/soml/code/code.rb create mode 100644 lib/soml/code/field_access.rb create mode 100644 lib/soml/code/if_statement.rb create mode 100644 lib/soml/code/operator_expression.rb create mode 100644 lib/soml/code/return_statement.rb create mode 100644 lib/soml/code/statements.rb create mode 100644 lib/soml/code/to_code.rb create mode 100644 lib/soml/code/while_statement.rb delete mode 100644 test/cases/array_constant/array_list.tst delete mode 100644 test/cases/array_constant/array_ops.tst delete mode 100644 test/cases/array_constant/one_array.tst delete mode 100644 test/cases/hash_constant/hash.tst delete mode 100644 test/cases/hash_constant/hash2.tst delete mode 100644 test/cases/hash_constant/hash_list.tst diff --git a/lib/soml-parser.rb b/lib/soml-parser.rb index 446d718..554bde2 100644 --- a/lib/soml-parser.rb +++ b/lib/soml-parser.rb @@ -2,3 +2,4 @@ require 'parslet' require 'parser/soml' require "ast" require 'parser/transform' +require "soml/code/code" diff --git a/lib/soml/code/assignment.rb b/lib/soml/code/assignment.rb new file mode 100644 index 0000000..1096d3b --- /dev/null +++ b/lib/soml/code/assignment.rb @@ -0,0 +1,5 @@ +module Soml + class Assignment < Statement + attr_accessor :name , :value + end +end diff --git a/lib/soml/code/basic_values.rb b/lib/soml/code/basic_values.rb new file mode 100644 index 0000000..38b6854 --- /dev/null +++ b/lib/soml/code/basic_values.rb @@ -0,0 +1,38 @@ +module Soml + class IntegerExpression < Expression + attr_accessor :value + def initialize(value) + @value = value + end + end + class FloatExpression < Expression + attr_accessor :value + def initialize(value) + @value = value + end + end + class TrueExpression < Expression + end + class FalseExpression < Expression + end + class NilExpression < Expression + end + class StringExpression < Expression + attr_accessor :value + def initialize(value) + @value = value + end + end + class NameExpression < Expression + attr_accessor :value + def initialize(value) + @value = value + end + end + class ClassExpression < Expression + attr_accessor :value + def initialize(value) + @value = value + end + end +end diff --git a/lib/soml/code/call_site.rb b/lib/soml/code/call_site.rb new file mode 100644 index 0000000..f02a4a6 --- /dev/null +++ b/lib/soml/code/call_site.rb @@ -0,0 +1,5 @@ +module Soml + class CallSite < Expression + attr_accessor :name , :receiver , :arguments + end +end diff --git a/lib/soml/code/code.rb b/lib/soml/code/code.rb new file mode 100644 index 0000000..e5201d1 --- /dev/null +++ b/lib/soml/code/code.rb @@ -0,0 +1,25 @@ + +# Base class for Expresssion and Statement +module Soml + + class Code + + end + + class Statement < Code + end + class Expression < Code + end + +end + +require_relative "while_statement" +require_relative "if_statement" +require_relative "return_statement" +require_relative "statements" +require_relative "operator_expression" +require_relative "field_access" +require_relative "call_site" +require_relative "basic_values" +require_relative "assignment" +require_relative "to_code" diff --git a/lib/soml/code/field_access.rb b/lib/soml/code/field_access.rb new file mode 100644 index 0000000..fdc887a --- /dev/null +++ b/lib/soml/code/field_access.rb @@ -0,0 +1,5 @@ +module Soml + class FieldAccess < Expression + attr_accessor :receiver , :field + end +end diff --git a/lib/soml/code/if_statement.rb b/lib/soml/code/if_statement.rb new file mode 100644 index 0000000..dcd62c7 --- /dev/null +++ b/lib/soml/code/if_statement.rb @@ -0,0 +1,5 @@ +module Soml + class IfStatement < Statement + attr_accessor :branch_type , :condition , :if_true , :if_false + end +end diff --git a/lib/soml/code/operator_expression.rb b/lib/soml/code/operator_expression.rb new file mode 100644 index 0000000..2c0224d --- /dev/null +++ b/lib/soml/code/operator_expression.rb @@ -0,0 +1,5 @@ +module Soml + class OperatorExpression < Expression + attr_accessor :operator , :left_expression , :right_expression + end +end diff --git a/lib/soml/code/return_statement.rb b/lib/soml/code/return_statement.rb new file mode 100644 index 0000000..cb277fb --- /dev/null +++ b/lib/soml/code/return_statement.rb @@ -0,0 +1,5 @@ +module Soml + class ReturnStatement < Statement + attr_accessor :return_value + end +end diff --git a/lib/soml/code/statements.rb b/lib/soml/code/statements.rb new file mode 100644 index 0000000..f416f69 --- /dev/null +++ b/lib/soml/code/statements.rb @@ -0,0 +1,5 @@ +module Soml + class Statements < Statement + attr_accessor :statements + end +end diff --git a/lib/soml/code/to_code.rb b/lib/soml/code/to_code.rb new file mode 100644 index 0000000..3989c24 --- /dev/null +++ b/lib/soml/code/to_code.rb @@ -0,0 +1,108 @@ +module Soml + + def self.ast_to_code statement + compiler = ToCode.new + compiler.process statement + end + + class ToCode < AST::Processor + + 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.statements = process_all(statements) + w + end + + def on_if_statement statement + branch_type , condition , if_true , if_false = *statement + w = IfStatement.new() + w.branch_type = branch_type + w.condition = process(condition) #.first + w.if_true = process_all(if_true) + w.if_false = process_all(if_false) + w + end + + def on_statements statement + w = Statements.new() + w.statements = process_all(statement.children) + w + end + + def on_return statement + w = ReturnStatement.new() + w.return_value = process(statement.children.first) + w + end + + def on_operator_value statement + operator , left_e , right_e = *statement + w = OperatorExpression.new() + w.operator = operator + w.left_expression = process(left_e) + w.right_expression = process(right_e) + w + end + + def on_field_access statement + receiver_ast , field_ast = *statement + w = FieldAccess.new() + w.receiver = process(receiver_ast) + w.field = process(field_ast) + w + end + + def on_receiver expression + process expression.children.first + end + + def on_call statement + name_s , arguments , receiver = *statement + w = CallSite.new() + w.name = name_s + w.arguments = process(arguments) + w.receiver = process(receiver) + w + end + + def on_int expression + IntegerExpression.new(expression.children.first) + end + + def on_true expression + TrueExpression.new + end + + def on_false expression + FalseExpression.new + end + + def on_nil expression + NilExpression.new + end + + def on_name statement + NameExpression.new(statement.children.first) + end + def on_string expression + StringExpression.new(expression.children.first) + end + + def on_class_name expression + ClassExpression.new(expression.children.first) + end + + def on_assignment statement + name , value = *statement + w = Assignment.new() + w.name = process name + w.value = process(value) + w + end + + end +end diff --git a/lib/soml/code/while_statement.rb b/lib/soml/code/while_statement.rb new file mode 100644 index 0000000..3b9c786 --- /dev/null +++ b/lib/soml/code/while_statement.rb @@ -0,0 +1,5 @@ +module Soml + class WhileStatement < Statement + attr_accessor :branch_type , :condition , :statements + end +end diff --git a/test/README.md b/test/README.md index 1c8cf52..36a933d 100644 --- a/test/README.md +++ b/test/README.md @@ -8,8 +8,10 @@ to run just a single, replace all with what you want to test. Minitest accept a ruby test/test_class.rb -n test_class_ops_parse -Notice tough the "_parse" at the end, while you will find no such function. The Magic (explained below) renerates three -functions per case. Your options are "_parse" , "_transform" , or if it's really bad, "_ast" (this should really work when the previous two work) +Notice tough the "_parse" at the end, while you will find no such function. +The Magic (explained below) generates three functions per case. +Your options are "_parse" , "_transform" , or if it's really bad, "_ast" +(this should really work when the previous two work) ### Directories @@ -26,7 +28,7 @@ Apart from just plain more tests, two additional directories are planned. One is Parsing is a two step process with parslet: - parse takes an input and outputs hashes/arrays with basic types - - tramsform takes the output of parse and generates an ast (as specified by the transformation) + - transform takes the output of parse and generates an ast (as specified by the transformation) A test tests both phases separately and again together. Each test must thus specify (as instance variables): diff --git a/test/cases/array_constant/array_list.tst b/test/cases/array_constant/array_list.tst deleted file mode 100644 index 10fa31e..0000000 --- a/test/cases/array_constant/array_list.tst +++ /dev/null @@ -1,5 +0,0 @@ -[42, foo] --- -- -- -s(:array, - s(:int, 42), - s(:name, :foo)) diff --git a/test/cases/array_constant/array_ops.tst b/test/cases/array_constant/array_ops.tst deleted file mode 100644 index 7b90e95..0000000 --- a/test/cases/array_constant/array_ops.tst +++ /dev/null @@ -1,10 +0,0 @@ -[ 3 + 4 , foo(22) ] --- -- -- -s(:array, - s(:operator_value, :+, - s(:int, 3), - s(:int, 4)), - s(:call, - s(:name, :foo), - s(:arguments, - s(:int, 22)))) diff --git a/test/cases/array_constant/one_array.tst b/test/cases/array_constant/one_array.tst deleted file mode 100644 index 2271d2c..0000000 --- a/test/cases/array_constant/one_array.tst +++ /dev/null @@ -1,4 +0,0 @@ -[42] --- -- -- -s(:array, - s(:int, 42)) diff --git a/test/cases/hash_constant/hash.tst b/test/cases/hash_constant/hash.tst deleted file mode 100644 index 75f4e39..0000000 --- a/test/cases/hash_constant/hash.tst +++ /dev/null @@ -1,6 +0,0 @@ -{ foo => 33 } --- -- -- -s(:hash, - s(:assoc, - s(:name, :foo), - s(:int, 33))) diff --git a/test/cases/hash_constant/hash2.tst b/test/cases/hash_constant/hash2.tst deleted file mode 100644 index d6781fb..0000000 --- a/test/cases/hash_constant/hash2.tst +++ /dev/null @@ -1,6 +0,0 @@ -{ foo => true } --- -- -- -s(:hash, - s(:assoc, - s(:name, :foo), - s(:true))) diff --git a/test/cases/hash_constant/hash_list.tst b/test/cases/hash_constant/hash_list.tst deleted file mode 100644 index b77db50..0000000 --- a/test/cases/hash_constant/hash_list.tst +++ /dev/null @@ -1,9 +0,0 @@ -{foo => 33 , bar => 42} --- -- -- -s(:hash, - s(:assoc, - s(:name, :foo), - s(:int, 33)), - s(:assoc, - s(:name, :bar), - s(:int, 42))) diff --git a/test/test_all.rb b/test/test_all.rb index 3977046..906685d 100644 --- a/test/test_all.rb +++ b/test/test_all.rb @@ -34,6 +34,12 @@ class TestAll < MiniTest::Test end end assert_equal sexp , result + check_transform sexp + end + + def check_transform sexp + code = Soml.ast_to_code sexp + assert code.is_a?(Soml::Code) , "Returned #{code}" end # this creates test methods dynamically. For each test_* method we create