35 Commits

Author SHA1 Message Date
56a02bd6ea use ast that produces ruby output 2016-12-08 19:34:59 +02:00
f5b54c5fca add cli for soml->s-exp 2016-12-08 18:54:27 +02:00
5c03db709f fix if false logic 2016-03-07 11:51:58 +02:00
324c9c2eae better handling of statement lists 2016-03-07 11:32:28 +02:00
c9d25fcf81 easier constructor 2016-03-07 11:32:09 +02:00
f51ed376c4 add missing as types 2016-03-06 14:07:25 +02:00
4a9b492dd9 move to typed structure
on the way to removing the language, the at needs to be replaced with a
typed structure.
2016-03-06 09:40:41 +02:00
9ca03ef115 hopefully fix travis issue 2015-11-30 20:07:11 +02:00
d38a9c626f renamed to soml-parser 2015-11-30 19:55:48 +02:00
6ae4b624b0 leaving the name for field defs
so we can reuse that expression
so we can highlight it in the debugger
2015-11-02 20:10:05 +02:00
335a6b1e37 update parsley 2015-11-02 20:09:13 +02:00
6710567af9 fix test after syntax changes 2015-10-19 15:21:23 +03:00
3061ddfed9 same syntax change for while_xxx
xxx can be any string for the parser
the language will restrict if somewhat later
2015-10-19 15:21:11 +03:00
7cc7ab5c18 adding condition to if statement
new syntax is if_true( . .. . )
where any string is allowed in case of true
2015-10-19 15:10:38 +03:00
72ed05254e move control into statements 2015-10-19 14:57:03 +03:00
ab0a94bd51 change type to class name
although int is still allowed for integers (gets replaced though)
2015-10-14 15:48:53 +03:00
1b2802ecf4 use bundlers rake tasks 2015-10-10 21:52:14 +03:00
6bd5e9b5ee version bump for lots of incompatible changes 2015-10-09 17:34:10 +03:00
be07cd615a transform changes for what was basically a rewrite 2015-10-09 17:32:55 +03:00
e9a7b1f6da fix root, much tighter now 2015-10-09 17:32:34 +03:00
3651856fc5 fix class defs 2015-10-09 17:32:05 +03:00
60746383ee expressions are now statements 2015-10-09 17:31:08 +03:00
b424306156 fix array and hash constants, now seperated out 2015-10-09 17:29:24 +03:00
dff0e8fab4 fix function definition 2015-10-09 17:28:47 +03:00
48a6dfabff fix while and if statements 2015-10-09 17:28:13 +03:00
7f2f64c713 fix call site and now seperated assignment (was bunged as operator) 2015-10-09 17:27:22 +03:00
c9942ec516 test field access seperately (was mixed in) 2015-10-09 17:25:43 +03:00
af8febe456 fix operators, only binary 2015-10-09 17:25:09 +03:00
ba7ecbfa7b fix basic types 2015-10-09 17:24:23 +03:00
97cf5e5bea retrying with the root of the directory
comes from finally tightning the root and not allowing random
expression code ala ruby
2015-10-09 17:23:43 +03:00
f7dcf2a2ff renameing to match expressions 2015-10-09 17:21:15 +03:00
85adfa7107 may call with r_value 2015-10-09 12:47:03 +03:00
308c0efc05 rename value_expression to r_value 2015-10-09 12:42:50 +03:00
77cb8ce90a restrict the root, but expand for testing 2015-10-09 12:39:31 +03:00
486e24514b there goes the module
it was ruby after all
should be reborn as twins: namespace and aspect
2015-10-08 22:57:39 +03:00
157 changed files with 1212 additions and 1142 deletions

View File

@ -2,16 +2,14 @@ source "http://rubygems.org"
gem "rake"
gem "salama-reader" , :path => "."
gem "soml-parser" , :path => "."
# use this for debugging, the printout is better (cut/paste)
gem "ast" , :github => "dancinglightning/ast" , :branch => :new_inspect
#gem "ast"
gem "ast" , :github => "dancinglightning/ast"
# Add dependencies to develop your gem here.
# Include everything needed to run rake, tests, features, etc.
group :development do
gem "codeclimate-test-reporter", require: nil
gem "minitest"
gem "rubygems-tasks"
end

View File

@ -1,16 +1,15 @@
GIT
remote: git://github.com/dancinglightning/ast.git
revision: a9bc29377a94d2194e92596aceb9be7c7db4c8f8
branch: new_inspect
revision: 3814fb102af82a30bf334005ebe17332744f9dad
specs:
ast (2.1.0)
PATH
remote: .
specs:
salama-reader (0.3.0)
soml-parser (0.5.0)
ast (~> 2.1.0)
parslet (~> 1.7.0)
parslet (~> 1.7.1)
GEM
remote: http://rubygems.org/
@ -24,7 +23,6 @@ GEM
parslet (1.7.1)
blankslate (>= 2.0, <= 4.0)
rake (10.4.2)
rubygems-tasks (0.2.4)
simplecov (0.9.2)
docile (~> 1.1.0)
multi_json (~> 1.0)
@ -39,8 +37,7 @@ DEPENDENCIES
codeclimate-test-reporter
minitest
rake
rubygems-tasks
salama-reader!
soml-parser!
BUNDLED WITH
1.10.6
1.13.5

View File

@ -1,17 +1,17 @@
[![Build Status](https://travis-ci.org/salama/salama-reader.svg?branch=master)](https://travis-ci.org/salama/salama-reader)
[![Gem Version](https://badge.fury.io/rb/salama-reader.svg)](http://badge.fury.io/rb/salama-reader)
[![Test Coverage](https://codeclimate.com/github/salama/salama-reader/badges/coverage.svg)](https://codeclimate.com/github/salama/salama-reader)
[![Build Status](https://travis-ci.org/salama/soml-parser.svg?branch=master)](https://travis-ci.org/salama/soml-parser)
[![Gem Version](https://badge.fury.io/rb/soml-parser.svg)](http://badge.fury.io/rb/soml-parser)
[![Test Coverage](https://codeclimate.com/github/salama/soml-parser/badges/coverage.svg)](https://codeclimate.com/github/salama/soml-parser)
## Salama Reader
## Soml Parser
The parser part of salama is now a standalone gem. It parses Phisol using Parslet and no other dependencies.
The parser part of soml is a standalone gem to allow independent development.
It parses Soml using Parslet and no other dependencies.
Also it is very educational, as it is very readable code, and not too much of it.
## Phisol Phi System Object Language
## Soml: Salama Object Machine Language
Phisol is just forming after realizing the (unfortunate) need for an oo system language.
(I really didn't want to do yet another language)
Soml is Still forming after realizing the need for an oo system language.
The need comes from these three things:
@ -20,26 +20,18 @@ Phisol is just forming after realizing the (unfortunate) need for an oo system l
- Upward compatible memory and calling conventions are needed
- Multiple return addresses are needed
From these comes the name: A phi node is the opposite of what you may think of as an if. Actually an
if statement is always a branch (the if part) and a rejoining of the two branches (the phi part).
In Phisol a function call is not necessarily a part of linear code. A call may return to several
In Soml a function call is not necessarily a part of linear code. A call may return to several
addresses, making the call more like an if statement.
### Syntax
Syntax (and semantics) of Phisol are just forming, but some things are clear:
Syntax and semantics of Soml are described on the [salama site](http://salama-vm.org/soml/soml.html)
- statically typed (in the beginning with just two types) meaning all variable declarations,
functions and arguments shall be typed.
- statically typed so all variable declarations, functions and arguments are typed.
- objects but without data hiding
- probably nil objects
- static blocks (a bit ala crystal)
- call syntax as already discussed, ie message based
Some things we shall leave behind from the ruby approach are a lot of sugar, like missing brackets,
random code everywhere, expressions galore . . .
- no semicolns and stuff, but not ruby either
### Parser
@ -52,10 +44,10 @@ Most names are quite self explanatory, but here is a list:
- call_site is a function call. May be qualified, but currently must still have braches
- compound types are hash and array definitions. Hashes still need curlies
- control is if statement which still must have an else
- expression is a helper for all code allowed in a function
- statement is a helper for all code allowed in a function
- function definition must have braces too
- keywords is just a list of them
- operator expression are binary operators (see also below). There's a surprising amount
- operator statement are binary operators (see also below). There's a surprising amount
- return statement are straightforward
- while still needs a do, though i think in ruby a newline is sufficient

View File

@ -11,9 +11,7 @@ rescue Bundler::BundlerError => e
end
require 'rake'
require 'rubygems/tasks'
Gem::Tasks.new
require "bundler/gem_tasks"
require 'rake/testtask'
Rake::TestTask.new(:test) do |test|
@ -29,7 +27,7 @@ Rake::RDocTask.new do |rdoc|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
rdoc.rdoc_dir = 'rdoc'
rdoc.title = "salama-reader #{version}"
rdoc.title = "soml-parser #{version}"
rdoc.rdoc_files.include('README*')
rdoc.rdoc_files.include('lib/**/*.rb')
end

View File

@ -36,27 +36,29 @@ module Parser
rule(:digit) { match('[0-9]') }
rule(:exponent) { (str('e')| str('E')) }
rule(:type) { (str("int") | str("ref")).as(:type) >> space }
rule(:type) { (str("int") | class_name).as(:type) >> space }
# identifier must start with lower case
# TODO rule forbit names like if_true, because it starts with a keyword. a little looser please!
# TODO rule forbit names like true_statements, because it starts with a keyword. a little looser please!
rule(:name) { (keyword|type).absent? >> (match['a-z_'] >> match['a-zA-Z0-9_'].repeat).as(:name) >> space? }
# fields have type
rule(:field) { type >> name >> (assign >> value_expression.as(:value) ).maybe}
rule(:class_field) { keyword_field >> field }
# and class/module names must start with capital
rule(:module_name) { keyword.absent? >> (match['A-Z'] >> match['a-zA-Z0-9_'].repeat).as(:module_name) >> space? }
rule(:class_name) { keyword.absent? >> (match['A-Z'] >> match['a-zA-Z0-9_'].repeat).as(:class_name) >> space? }
rule(:escape) { str('\\') >> any.as(:esc) }
rule(:string) { quote >> (
escape |
nonquote.as(:char)
).repeat(1).as(:string) >> quote }
).repeat(1).as(:string) >> quote >> space? }
rule(:integer) { sign.maybe >> digit.repeat(1).as(:integer) >> space? }
rule(:float) { integer >> dot >> integer >>
(exponent >> sign.maybe >> digit.repeat(1,3)).maybe >> space?}
rule(:basic_type){ integer | name | string | float | field | module_name |
keyword_true | keyword_false | keyword_nil }
rule(:field_access) { name.as(:receiver) >> str(".") >> name.as(:field) }
rule(:basic_type){ integer | name | string | float | class_name |
((keyword_true | keyword_false | keyword_nil) >> space? ) }
end
end

View File

@ -2,17 +2,22 @@ module Parser
module CallSite
include Parslet
rule(:r_value) { operator_value | call_site | field_access | basic_type }
rule(:assign) { str('=') >> space?}
rule(:assignment){ (field_access|name).as(:l_value) >> assign.as(:assign) >> r_value.as(:r_value) }
rule(:field_def) { type >> name >> (assign >> r_value.as(:value) ).maybe}
rule(:argument_list) {
left_parenthesis >>
( (basic_type.as(:argument) >>
(comma >> basic_type.as(:argument)).repeat(0)).repeat(0,1)).as(:argument_list) >>
(comma >> r_value.as(:argument)).repeat(0)).repeat(0,1)).as(:argument_list) >>
right_parenthesis
}
rule(:call_site) { (basic_type.as(:receiver) >> str(".")).maybe >> #possibly qualified
name.as(:call_site) >> argument_list >> comment.maybe}
rule(:field_access) { name.as(:receiver) >> str(".") >> name.as(:field) }
end
end

View File

@ -0,0 +1,16 @@
module Parser
module ModuleDef
include Parslet
rule(:class_field) { keyword_field >> field_def }
rule(:class_body) {
function_definition | class_field
}
rule(:class_definition) do
keyword_class >> class_name >> (str("<") >> space >> class_name).maybe.as(:derived_name) >>
( (keyword_end.absent? >> class_body).repeat()).as(:class_statements) >> keyword_end
end
end
end

View File

@ -5,12 +5,12 @@ module Parser
rule(:array_constant) do
left_bracket >>
( ((operator_expression|value_expression).as(:array_element) >> space? >>
(comma >> space? >> (operator_expression|value_expression).as(:array_element)).repeat(0)).repeat(0,1)).as(:array_constant) >>
( (r_value.as(:array_element) >> space? >>
(comma >> space? >> r_value.as(:array_element)).repeat(0)).repeat(0,1)).as(:array_constant) >>
space? >> right_bracket
end
rule(:hash_pair) { basic_type.as(:hash_key) >> association >> (operator_expression|value_expression).as(:hash_value) }
rule(:hash_pair) { basic_type.as(:hash_key) >> association >> r_value.as(:hash_value) }
rule(:hash_constant) { left_brace >> ((hash_pair.as(:hash_pair) >>
(comma >> space? >> hash_pair.as(:hash_pair)).repeat(0)).repeat(0,1)).as(:hash_constant)>>
space? >> right_brace }

View File

@ -1,24 +0,0 @@
module Parser
module Control
include Parslet
rule(:conditional) do
keyword_if >>
left_parenthesis >> (operator_expression|value_expression).as(:conditional) >> right_parenthesis >>
expressions_else.as(:if_true) >> expressions_end.as(:if_false)
end
rule(:small_conditional) do
keyword_if >>
left_parenthesis >> (operator_expression|value_expression).as(:conditional) >> right_parenthesis >>
expressions_end.as(:if_true)
end
rule(:while_do) do
keyword_while >> left_parenthesis >> (operator_expression|value_expression).as(:while_cond) >>
right_parenthesis >> expressions_end.as(:body)
end
rule(:simple_return) do
keyword_return >> (operator_expression|value_expression).as(:return_expression)
end
end
end

View File

@ -1,20 +0,0 @@
module Parser
module Expression
include Parslet
rule(:value_expression) { call_site | field_access |basic_type }
rule(:expression) { (simple_return | while_do | small_conditional | conditional |
operator_expression | call_site | class_field | field |
hash_constant | array_constant) }
def delimited_expressions( delimit )
( (delimit.absent? >> expression).repeat(1)).as(:expressions) >> delimit
end
rule(:expressions_do) { delimited_expressions(keyword_do) }
rule(:expressions_else) { delimited_expressions(keyword_else) }
rule(:expressions_end) { delimited_expressions(keyword_end) }
end
end

View File

@ -3,13 +3,13 @@ module Parser
include Parslet
rule(:function_definition) {
type >> ((module_name|name).as(:receiver) >> str(".")).maybe >> #possibly qualified
type >> ((class_name|name).as(:receiver) >> str(".")).maybe >> #possibly qualified
name.as(:function_name) >> left_parenthesis >>
parameter_list.maybe >> right_parenthesis >> expressions_end >> space?
parameter_list.maybe >> right_parenthesis >> statements_end >> space?
}
rule(:parameter_list) {
((field.as(:parameter) >> (comma >> field.as(:parameter)).repeat(0)).repeat(0,1)).as(:parameter_list)
((field_def.as(:parameter) >> (comma >> field_def.as(:parameter)).repeat(0)).repeat(0,1)).as(:parameter_list)
}
end

View File

@ -4,25 +4,18 @@ module Parser
rule(:keyword_begin) { str('begin').as(:begin) >> space?}
rule(:keyword_class) { str('class') >> space? }
rule(:keyword_do) { str('do').as(:do) >> space?}
rule(:keyword_else) { str('else').as(:else) >> space? }
rule(:keyword_end) { str('end').as(:end) >> space? }
rule(:keyword_false) { str('false').as(:false) }
rule(:keyword_field) { str('field').as(:field) >> space? }
rule(:keyword_if) { str('if').as(:if) }
rule(:keyword_rescue) { str('rescue').as(:rescue) >> space?}
rule(:keyword_return) { str('return').as(:return) >> space?}
rule(:keyword_true) { str('true').as(:true) }
rule(:keyword_module) { str('module') >> space? }
rule(:keyword_nil) { str('nil').as(:nil) }
rule(:keyword_unless) { str('unless').as(:unless) >> space?}
rule(:keyword_until) { str('until').as(:until) >> space?}
rule(:keyword_while) { str('while').as(:while) }
# this rule is just to make sure identifiers can't be keywords. Kind of duplication here, but we need the
# space in above rules, so just make sure to add any here too.
rule(:keyword){ str('begin') | str('def') | str('do') | str('else') | str('end') |
str('false')| str('if')| str('rescue')| str('true')| str('nil') |
str('unless')| str('until')| str('while') | str('field')}
rule(:keyword){ str('if_') | str('else') | str('end') | str('while_') |
str('false') | str('true')| str('nil') | str("class") |
str('return')| str('int')| str('field')}
end
end

View File

@ -1,15 +0,0 @@
module Parser
module ModuleDef
include Parslet
rule(:module_definition) do
keyword_module >> module_name >>
( (keyword_end.absent? >> root_body).repeat()).as(:module_expressions) >> keyword_end
end
rule(:class_definition) do
keyword_class >> module_name >> (smaller >> module_name).maybe.as(:derived_name) >>
( (keyword_end.absent? >> root_body).repeat()).as(:class_expressions) >> keyword_end
end
end
end

View File

@ -1,48 +1,15 @@
module Parser
module Operators
include Parslet
rule(:exponent) { str('**') >> space?}
rule(:multiply) { match['*/%'] >> space? }
rule(:plus) { match['+-'] >> space? }
rule(:shift) { str(">>") | str("<<") >> space?}
rule(:bit_and) { str('&') >> space?}
rule(:bit_or) { str('|') >> space?}
rule(:greater_equal) { str('>=') >> space?}
rule(:less_or_equal) { str('<=') >> space?}
rule(:larger) { str('>') >> space?}
rule(:smaller) { str('<') >> space?}
rule(:identity) { str('===') >> space?}
rule(:equal) { str('==') >> space?}
rule(:not_equal) { str('!=') >> space?}
rule(:boolean_and) { str('&&') | str("and") >> space?}
rule(:boolean_or) { str('||') | str("or") >> space?}
rule(:assign) { str('=') >> space?}
rule(:op_assign) { str('+=')|str('-=')|str('*=')|str('/=')|str('%=') >> space?}
rule(:eclipse) { str('..') |str("...") >> space?}
rule(:assign) { str('=') >> space?}
#infix doing the heavy lifting here,
# is defined as an expressions and array of [atoms,priority,binding] triples
rule(:operator_expression) do infix_expression(value_expression,
[exponent, 120, :left] ,
[multiply, 120, :left] ,
[plus, 110, :left],
[shift, 100, :left],
[bit_and, 90, :left],
[bit_or, 90, :right],
[greater_equal, 80, :left],
[less_or_equal, 80, :left],
[larger, 80, :left],
[smaller, 80, :left],
[identity, 70, :right],
[equal, 70, :right],
[not_equal, 70, :right],
[boolean_and, 60, :left],
[boolean_or, 50, :right],
[eclipse, 40, :right],
[keyword_rescue, 30, :right],
[assign, 20, :right],
[op_assign, 20, :right] ) >> space?
end
rule(:operator_sym) {
str('**') | str('*') | str('/') | str('/') | str('%') |
str('+') | str('-') | str('<<')| str('>>') |
str('|') | str('&') |
str('>=') | str('<=') | str('>') | str('<') |
str('==') | str('!=') }
rule(:operator_value) { (field_access|basic_type).as(:left) >>
operator_sym.as(:operator) >> space? >> (field_access|basic_type).as(:right) }
end
end

View File

@ -2,11 +2,10 @@ require_relative "basic_types"
require_relative "compound_types"
require_relative "tokens"
require_relative "keywords"
require_relative "control"
require_relative "expression"
require_relative "statement"
require_relative "call_site"
require_relative "function_definition"
require_relative "module_definition"
require_relative "class_definition"
require_relative "operators"
module Parser
@ -24,15 +23,13 @@ module Parser
include CompoundTypes
include Tokens
include Keywords
include Control
include Expression
include Statement
include CallSite
include FunctionDefinition
include Operators
include ModuleDef
rule(:root_body) {(module_definition | class_definition | function_definition |
expression | operator_expression | call_site )}
rule(:root) { root_body.repeat.as(:expression_list) }
rule(:root_body) {( class_definition | function_definition )}
rule(:root) { root_body.repeat.as(:statement_list) }
end
end

46
lib/parser/statement.rb Normal file
View File

@ -0,0 +1,46 @@
module Parser
module Statement
include Parslet
rule( :keyword_while) do
str("while_") >> alpha.repeat.as(:condition) >> space
end
rule(:while_statement) do
keyword_while >> left_parenthesis >> r_value.as(:conditional) >>
right_parenthesis >> statements_end.as(:body)
end
rule( :keyword_if) do
str("if_") >> alpha.repeat.as(:condition) >> space
end
rule(:if_statement) do
keyword_if >>
left_parenthesis >> r_value.as(:conditional) >> right_parenthesis >>
statements_else.as(:true_statements) >> statements_end.as(:false_statements)
end
rule(:small_conditional) do
keyword_if >>
left_parenthesis >> r_value.as(:conditional) >> right_parenthesis >>
statements_end.as(:true_statements)
end
rule(:return_statement) do
keyword_return >> r_value.as(:return_statement)
end
rule(:statement) { (return_statement | while_statement | small_conditional | if_statement |
assignment | class_field | field_def | call_site |
hash_constant | array_constant) }
def delimited_statements( delimit )
( (delimit.absent? >> statement).repeat(1)).as(:statements) >> delimit
end
rule(:statements_do) { delimited_statements(keyword_do) }
rule(:statements_else) { delimited_statements(keyword_else) }
rule(:statements_end) { delimited_statements(keyword_end) }
end
end

View File

@ -1,7 +1,17 @@
#include is private in 1.9, who'd have known without travis
Parslet::Context.send :include , AST::Sexp
Parslet::Context.class_eval do
def type_sym t
if( t.is_a? AST::Node )
t = t.children.first
else
t = t.to_sym
t = :Integer if t == :int
end
t
end
end
module Parser
class Transform < Parslet::Transform
@ -15,16 +25,22 @@ module Parser
rule(:integer => simple(:value)) { s(:int ,value.to_i) }
rule(:name => simple(:name)) { s(:name , name.to_sym) }
# local variables
rule(:type => simple(:type), :name => simple(:name)) { s(:field_def , type.to_sym , name.to_sym) }
rule(:type => simple(:type), :name => simple(:name)) {
s(:field_def , type_sym(type) , s(:name , name.to_sym)) }
rule(:type => simple(:type), :name => simple(:name) , :value => simple(:value)) {
s(:field_def , type.to_sym , name.to_sym , value ) }
s(:field_def , type_sym(type) , s(:name , name.to_sym) , value ) }
# class field
rule(:field => simple(:field) , :type => simple(:type), :name => simple(:name)) {
s(:class_field , type.to_sym , name.to_sym) }
s(:class_field , type_sym(type) , name.to_sym) }
rule(:field => simple(:field) , :type => simple(:type), :name => simple(:name) , :value => simple(:value)) {
s(:class_field , type.to_sym , name.to_sym , value ) }
s(:class_field , type_sym(type) , name.to_sym , value ) }
rule(:module_name => simple(:module_name)) { s(:module,module_name.to_s) }
rule(:l_value => simple(:l_value) , :assign => simple(:assign) , :r_value => simple(:r_value)) {
s(:assignment , l_value , r_value)
}
rule( :left => simple(:left) , :operator => simple(:operator) ,
:right => simple(:right)) { s(:operator_value , operator.to_sym , left , right )}
rule(:class_name => simple(:class_name)) { s(:class_name,class_name.to_s.to_sym) }
rule(:array_constant => sequence(:array_constant) ) { s(:array , *array_constant) }
rule(:array_element => simple(:array_element)) { array_element }
@ -48,68 +64,59 @@ module Parser
s(:field_access , s(:receiver , receiver) , s(:field , field) )
end
rule(:if => simple(:if), :conditional => simple(:conditional),
:if_true => {:expressions => sequence(:if_true) , :else => simple(:else) },
:if_false => {:expressions => sequence(:if_false) , :end => simple(:e) }) do
s(:if , s(:condition, conditional), s(:if_true, *if_true), s(:if_false , *if_false))
rule(:condition => simple(:condition) ,
:conditional => simple(:conditional),
:body => {:statements => sequence(:body) , :end => simple(:e) }) do
s(:while_statement,condition.to_s.to_sym, s(:conditional , conditional), s(:statements , *body))
end
rule(:if => simple(:if), :conditional => simple(:conditional),
:if_true => {:expressions => sequence(:if_true) , :end => simple(:e) }) do
s(:if , s(:condition, conditional), s(:if_true, *if_true), s(:if_false , nil) )
rule(:condition => simple(:condition), :conditional => simple(:conditional),
:true_statements => {:statements => sequence(:true_statements) , :else => simple(:else) },
:false_statements => {:statements => sequence(:false_statements) , :end => simple(:e) }) do
s(:if_statement, condition.to_s.to_sym,
s(:condition, conditional),
s(:true_statements, *true_statements),
s(:false_statements , *false_statements))
end
rule(:while => simple(:while),
:while_cond => simple(:while_cond) ,
:body => {:expressions => sequence(:body) , :end => simple(:e) }) do
s(:while , s(:condition , while_cond), s(:expressions , *body))
end
rule(:condition => simple(:condition), :conditional => simple(:conditional),
:true_statements => {:statements => sequence(:true_statements) , :end => simple(:e) }) do
s(:if_statement, condition.to_s.to_sym, s(:condition, conditional),
s(:true_statements, *true_statements), s(:false_statements , nil) )
end
rule(:return => simple(:return) , :return_expression => simple(:return_expression))do
s(:return , return_expression)
rule(:return => simple(:return) , :return_statement => simple(:return_statement))do
s(:return , return_statement)
end
rule(:parameter => simple(:parameter)) { s(:parameter , *parameter) }
rule(:parameter => simple(:parameter)) { s(:parameter , parameter.children[0] , parameter.children[1].children[0]) }
# Also two rules for function definitions, unqualified and qualified
rule(:type => simple(:type) ,
:function_name => simple(:function_name),
:parameter_list => sequence(:parameter_list),
:expressions => sequence(:expressions) , :end => simple(:e)) do
s(:function, type.to_sym , function_name, s(:parameters , *parameter_list ),
s(:expressions , *expressions))
:statements => sequence(:statements) , :end => simple(:e)) do
s(:function, type_sym(type) , function_name, s(:parameters , *parameter_list ),
s(:statements , *statements))
end
rule(:type => simple(:type) ,
:receiver=> simple(:receiver),
:function_name => simple(:function_name),
:parameter_list => sequence(:parameter_list),
:expressions => sequence(:expressions) , :end => simple(:e)) do
s(:function, type.to_sym , function_name, s(:parameters , *parameter_list ),
s(:expressions , *expressions) , s(:receiver , *receiver))
:statements => sequence(:statements) , :end => simple(:e)) do
s(:function, type_sym(type) , function_name, s(:parameters , *parameter_list ),
s(:statements , *statements) , s(:receiver , *receiver))
end
rule(l: simple(:l), o: simple(:o) , r: simple(:r)) do
op = o.to_s.strip
if op == "="
s(:assign , l ,r)
else
s(:operator, op , l ,r)
end
end
#modules and classes are understandibly quite similar Class < Module
rule( :module_name => simple(:module_name) , :derived_name => simple(:derived_name) , :class_expressions => sequence(:class_expressions) , :end=>"end") do
s(:class , module_name.to_s.to_sym ,
rule( :class_name => simple(:class_name) , :derived_name => simple(:derived_name) , :class_statements => sequence(:class_statements) , :end=>"end") do
s(:class , class_name.to_s.to_sym ,
s(:derives, derived_name ? derived_name.to_a.first.to_sym : nil) ,
s(:expressions, *class_expressions) )
end
rule( :module_name => simple(:module_name) , :module_expressions => sequence(:module_expressions) , :end=>"end") do
s(:module , module_name.to_s.to_sym , s(:expressions, *module_expressions))
s(:statements, *class_statements) )
end
rule(:expression_list => sequence(:expression_list)) {
s(:expressions , *expression_list)
rule(:statement_list => sequence(:statement_list)) {
s(:statements , *statement_list)
}
#shortcut to get the ast tree for a given string

View File

@ -1,4 +1,5 @@
require 'parslet'
require 'parser/salama'
require 'parser/soml'
require "ast"
require 'parser/transform'
require "soml/code/code"

View File

@ -0,0 +1,13 @@
module Soml
class Assignment < Statement
attr_accessor :name , :value
def initialize(n = nil , v = nil )
@name , @value = n , v
end
end
class FieldDef < Statement
attr_accessor :name , :type , :value
end
end

View File

@ -0,0 +1,39 @@
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
alias :name :value
def initialize(value)
@value = value
end
end
class ClassExpression < Expression
attr_accessor :value
def initialize(value)
@value = value
end
end
end

View File

@ -0,0 +1,5 @@
module Soml
class CallSite < Expression
attr_accessor :name , :receiver , :arguments
end
end

View File

@ -0,0 +1,9 @@
module Soml
class ClassStatement < Statement
attr_accessor :name , :derives , :statements
end
class ClassField < Statement
attr_accessor :name , :type
end
end

27
lib/soml/code/code.rb Normal file
View File

@ -0,0 +1,27 @@
# 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 "class_statement"
require_relative "function_statement"
require_relative "to_code"

View File

@ -0,0 +1,5 @@
module Soml
class FieldAccess < Expression
attr_accessor :receiver , :field
end
end

View File

@ -0,0 +1,5 @@
module Soml
class FunctionStatement < Statement
attr_accessor :return_type , :name , :parameters, :statements , :receiver
end
end

View File

@ -0,0 +1,5 @@
module Soml
class IfStatement < Statement
attr_accessor :branch_type , :condition , :if_true , :if_false
end
end

View File

@ -0,0 +1,5 @@
module Soml
class OperatorExpression < Expression
attr_accessor :operator , :left_expression , :right_expression
end
end

View File

@ -0,0 +1,5 @@
module Soml
class ReturnStatement < Statement
attr_accessor :return_value
end
end

View File

@ -0,0 +1,5 @@
module Soml
class Statements < Statement
attr_accessor :statements
end
end

163
lib/soml/code/to_code.rb Normal file
View File

@ -0,0 +1,163 @@
module Soml
def self.ast_to_code statement
compiler = ToCode.new
compiler.process statement
end
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(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(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
branch_type , condition , statements = *statement
w = WhileStatement.new()
w.branch_type = branch_type
w.condition = process(condition)
w.statements = process(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)
w.if_true = process(if_true)
w.if_false = process(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()
return w unless statement.children
return w unless statement.children.first
w.statements = process_all(statement.children)
w
end
alias :on_true_statements :on_statements
alias :on_false_statements :on_statements
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.children.first
w.arguments = process_all(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

View File

@ -0,0 +1,5 @@
module Soml
class WhileStatement < Statement
attr_accessor :branch_type , :condition , :statements
end
end

View File

@ -1,19 +1,19 @@
# -*- encoding: utf-8 -*-
Gem::Specification.new do |s|
s.name = 'salama-reader'
s.version = '0.3.0'
s.name = 'soml-parser'
s.version = '0.5.0'
s.authors = ['Torsten Ruger']
s.email = 'torsten@villataika.fi'
s.extra_rdoc_files = ['README.md']
s.files = %w(README.md LICENSE) + Dir.glob("lib/**/*")
s.homepage = 'https://github.com/salama/salama-reader'
s.homepage = 'https://github.com/salama/soml-parser'
s.license = 'GNU v3'
s.require_paths = ['lib']
s.summary = 'Ruby parser for the salama machine'
s.summary = 'Ruby parser for the salama object system language'
s.add_dependency 'parslet', '~> 1.7.0'
s.add_dependency 'parslet', '~> 1.7.1'
s.add_dependency 'ast', '~> 2.1.0'
end

View File

@ -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):

View File

@ -0,0 +1,9 @@
self.a = 5
-- -- --
s(:assignment,
s(:field_access,
s(:receiver,
s(:name, :self)),
s(:field,
s(:name, :a))),
s(:int, 5))

View File

@ -0,0 +1,5 @@
name = 10
-- -- --
s(:assignment,
s(:name, :name),
s(:int, 10))

View File

@ -1,4 +0,0 @@
FooBar
-- -- --
s(:expressions,
s(:module, "FooBar"))

View File

@ -1,4 +0,0 @@
foo
-- -- --
s(:expressions,
s(:name, :foo))

View File

@ -1,4 +0,0 @@
foo_bar
-- -- --
s(:expressions,
s(:name, :foo_bar))

View File

@ -1,4 +0,0 @@
_bar
-- -- --
s(:expressions,
s(:name, :_bar))

View File

@ -1,4 +0,0 @@
42
-- -- --
s(:expressions,
s(:int, 42))

View File

@ -1,4 +0,0 @@
"hello"
-- -- --
s(:expressions,
s(:string, "hello"))

View File

@ -1,4 +0,0 @@
"hello \nyou"
-- -- --
s(:expressions,
s(:string, "hello \\nyou"))

View File

@ -0,0 +1,3 @@
FooBar
-- -- --
s(:class_name, :FooBar)

View File

@ -0,0 +1,3 @@
foo
-- -- --
s(:name, :foo)

View File

@ -0,0 +1,3 @@
foo_bar
-- -- --
s(:name, :foo_bar)

View File

@ -0,0 +1,3 @@
_bar
-- -- --
s(:name, :_bar)

View File

@ -0,0 +1,3 @@
42
-- -- --
s(:int, 42)

View File

@ -0,0 +1,2 @@
"hello"-- -- --
s(:string, "hello")

View File

@ -0,0 +1,2 @@
"hello \nyou"-- -- --
s(:string, "hello \\nyou")

View File

@ -1,8 +1,7 @@
puts(3 , a )
-- -- --
s(:expressions,
s(:call,
s(:name, :puts),
s(:arguments,
s(:int, 3),
s(:name, :a))))
s(:call,
s(:name, :puts),
s(:arguments,
s(:int, 3),
s(:name, :a)))

View File

@ -1,8 +1,7 @@
baz(42, foo)
-- -- --
s(:expressions,
s(:call,
s(:name, :baz),
s(:arguments,
s(:int, 42),
s(:name, :foo))))
s(:call,
s(:name, :baz),
s(:arguments,
s(:int, 42),
s(:name, :foo)))

View File

@ -1,7 +1,6 @@
puts( "hello")
-- -- --
s(:expressions,
s(:call,
s(:name, :puts),
s(:arguments,
s(:string, "hello"))))
s(:call,
s(:name, :puts),
s(:arguments,
s(:string, "hello")))

View File

@ -1,8 +0,0 @@
message.self
-- -- --
s(:expressions,
s(:field_access,
s(:receiver,
s(:name, :message)),
s(:field,
s(:name, :self))))

View File

@ -1,8 +1,7 @@
42.put()
-- -- --
s(:expressions,
s(:call,
s(:name, :put),
s(:arguments),
s(:receiver,
s(:int, 42))))
s(:call,
s(:name, :put),
s(:arguments),
s(:receiver,
s(:int, 42)))

View File

@ -1,7 +1,6 @@
puts( 5)
-- -- --
s(:expressions,
s(:call,
s(:name, :puts),
s(:arguments,
s(:int, 5))))
s(:call,
s(:name, :puts),
s(:arguments,
s(:int, 5)))

View File

@ -1,7 +1,6 @@
foo(42)
-- -- --
s(:expressions,
s(:call,
s(:name, :foo),
s(:arguments,
s(:int, 42))))
s(:call,
s(:name, :foo),
s(:arguments,
s(:int, 42)))

View File

@ -1,9 +1,8 @@
Object.foo(42)
-- -- --
s(:expressions,
s(:call,
s(:name, :foo),
s(:arguments,
s(:int, 42)),
s(:receiver,
s(:module, "Object"))))
s(:call,
s(:name, :foo),
s(:arguments,
s(:int, 42)),
s(:receiver,
s(:class_name, :Object)))

View File

@ -1,9 +1,8 @@
my_my.foo(42)
-- -- --
s(:expressions,
s(:call,
s(:name, :foo),
s(:arguments,
s(:int, 42)),
s(:receiver,
s(:name, :my_my))))
s(:call,
s(:name, :foo),
s(:arguments,
s(:int, 42)),
s(:receiver,
s(:name, :my_my)))

View File

@ -1,9 +1,8 @@
self.foo(42)
-- -- --
s(:expressions,
s(:call,
s(:name, :foo),
s(:arguments,
s(:int, 42)),
s(:receiver,
s(:name, :self))))
s(:call,
s(:name, :foo),
s(:arguments,
s(:int, 42)),
s(:receiver,
s(:name, :self)))

View File

@ -1,8 +1,7 @@
"hello".puts()
-- -- --
s(:expressions,
s(:call,
s(:name, :puts),
s(:arguments),
s(:receiver,
s(:string, "hello"))))
s(:call,
s(:name, :puts),
s(:arguments),
s(:receiver,
s(:string, "hello")))

View File

@ -1,15 +0,0 @@
class Foo < Object
int test()
43
end
end
-- -- --
s(:expressions,
s(:class, :Foo,
s(:derives, :Object),
s(:expressions,
s(:function, :int,
s(:name, :test),
s(:parameters),
s(:expressions,
s(:int, 43))))))

View File

@ -1,17 +0,0 @@
class Foo
module Boo
funcall(3 , var)
end
end
-- -- --
s(:expressions,
s(:class, :Foo,
s(:derives, nil),
s(:expressions,
s(:module, :Boo,
s(:expressions,
s(:call,
s(:name, :funcall),
s(:arguments,
s(:int, 3),
s(:name, :var))))))))

View File

@ -1,21 +0,0 @@
class Opers
int foo(int x)
int abba = 5
abba + 5
end
end
-- -- --
s(:expressions,
s(:class, :Opers,
s(:derives, nil),
s(:expressions,
s(:function, :int,
s(:name, :foo),
s(:parameters,
s(:parameter, :int, :x)),
s(:expressions,
s(:field_def, :int, :abba,
s(:int, 5)),
s(:operator, "+",
s(:name, :abba),
s(:int, 5)))))))

View File

@ -1,9 +0,0 @@
class Foo
5
end
-- -- --
s(:expressions,
s(:class, :Foo,
s(:derives, nil),
s(:expressions,
s(:int, 5))))

View File

@ -1,6 +1,6 @@
class String
ref self.new_string(int len )
String self.new_string(int len )
len = len << 2
return super.new_object( len)
end
@ -9,19 +9,19 @@ class String
return self.length
end
int plus(ref str)
int plus(String str)
my_length = self.length
str_len = str.length()
my_length = str_len + my_length
new_string = self.new_string(my_length )
i = 0
while( i < my_length)
while_plus( i - my_length)
char = get(i)
new_string.set(i , char)
i = i + 1
end
i = 0
while( i < str_len)
while_plus( i - str_len)
char = str.get(i)
len = i + my_length
new_string.set( len , char)
@ -32,18 +32,18 @@ class String
end
-- -- --
s(:expressions,
s(:statements,
s(:class, :String,
s(:derives, nil),
s(:expressions,
s(:function, :ref,
s(:statements,
s(:function, :String,
s(:name, :new_string),
s(:parameters,
s(:parameter, :int, :len)),
s(:expressions,
s(:assign,
s(:parameter, :Integer, :len)),
s(:statements,
s(:assignment,
s(:name, :len),
s(:operator, "<<",
s(:operator_value, :<<,
s(:name, :len),
s(:int, 2))),
s(:return,
@ -54,41 +54,41 @@ s(:expressions,
s(:receiver,
s(:name, :super))))),
s(:receiver, :self)),
s(:function, :int,
s(:function, :Integer,
s(:name, :length),
s(:parameters),
s(:expressions,
s(:statements,
s(:return,
s(:field_access,
s(:receiver,
s(:name, :self)),
s(:field,
s(:name, :length)))))),
s(:function, :int,
s(:function, :Integer,
s(:name, :plus),
s(:parameters,
s(:parameter, :ref, :str)),
s(:expressions,
s(:assign,
s(:parameter, :String, :str)),
s(:statements,
s(:assignment,
s(:name, :my_length),
s(:field_access,
s(:receiver,
s(:name, :self)),
s(:field,
s(:name, :length)))),
s(:assign,
s(:assignment,
s(:name, :str_len),
s(:call,
s(:name, :length),
s(:arguments),
s(:receiver,
s(:name, :str)))),
s(:assign,
s(:assignment,
s(:name, :my_length),
s(:operator, "+",
s(:operator_value, :+,
s(:name, :str_len),
s(:name, :my_length))),
s(:assign,
s(:assignment,
s(:name, :new_string),
s(:call,
s(:name, :new_string),
@ -96,16 +96,16 @@ s(:expressions,
s(:name, :my_length)),
s(:receiver,
s(:name, :self)))),
s(:assign,
s(:assignment,
s(:name, :i),
s(:int, 0)),
s(:while,
s(:condition,
s(:operator, "<",
s(:while_statement, :plus,
s(:conditional,
s(:operator_value, :-,
s(:name, :i),
s(:name, :my_length))),
s(:expressions,
s(:assign,
s(:statements,
s(:assignment,
s(:name, :char),
s(:call,
s(:name, :get),
@ -118,21 +118,21 @@ s(:expressions,
s(:name, :char)),
s(:receiver,
s(:name, :new_string))),
s(:assign,
s(:assignment,
s(:name, :i),
s(:operator, "+",
s(:operator_value, :+,
s(:name, :i),
s(:int, 1))))),
s(:assign,
s(:assignment,
s(:name, :i),
s(:int, 0)),
s(:while,
s(:condition,
s(:operator, "<",
s(:while_statement, :plus,
s(:conditional,
s(:operator_value, :-,
s(:name, :i),
s(:name, :str_len))),
s(:expressions,
s(:assign,
s(:statements,
s(:assignment,
s(:name, :char),
s(:call,
s(:name, :get),
@ -140,9 +140,9 @@ s(:expressions,
s(:name, :i)),
s(:receiver,
s(:name, :str)))),
s(:assign,
s(:assignment,
s(:name, :len),
s(:operator, "+",
s(:operator_value, :+,
s(:name, :i),
s(:name, :my_length))),
s(:call,
@ -152,9 +152,9 @@ s(:expressions,
s(:name, :char)),
s(:receiver,
s(:name, :new_string))),
s(:assign,
s(:assignment,
s(:name, :i),
s(:operator, "+",
s(:operator_value, :+,
s(:name, :i),
s(:int, 1))))),
s(:return,

View File

@ -3,27 +3,21 @@ class Foo < Object
int func()
return self.fff
end
ofthen(3 , var)
end
-- -- --
s(:expressions,
s(:statements,
s(:class, :Foo,
s(:derives, :Object),
s(:expressions,
s(:class_field, :int, :fff,
s(:statements,
s(:class_field, :Integer, :fff,
s(:int, 3)),
s(:function, :int,
s(:function, :Integer,
s(:name, :func),
s(:parameters),
s(:expressions,
s(:statements,
s(:return,
s(:field_access,
s(:receiver,
s(:name, :self)),
s(:field,
s(:name, :fff)))))),
s(:call,
s(:name, :ofthen),
s(:arguments,
s(:int, 3),
s(:name, :var))))))
s(:name, :fff)))))))))

View File

@ -1,30 +1,24 @@
class Pifi
ofthen(3 , var)
int self.ofthen(int n , ref m)
int self.ofthen(int n , Object m)
n = n + m.index
return n
end
end
-- -- --
s(:expressions,
s(:statements,
s(:class, :Pifi,
s(:derives, nil),
s(:expressions,
s(:call,
s(:name, :ofthen),
s(:arguments,
s(:int, 3),
s(:name, :var))),
s(:function, :int,
s(:statements,
s(:function, :Integer,
s(:name, :ofthen),
s(:parameters,
s(:parameter, :int, :n),
s(:parameter, :ref, :m)),
s(:expressions,
s(:assign,
s(:parameter, :Integer, :n),
s(:parameter, :Object, :m)),
s(:statements,
s(:assignment,
s(:name, :n),
s(:operator, "+",
s(:operator_value, :+,
s(:name, :n),
s(:field_access,
s(:receiver,

View File

@ -1,6 +1,6 @@
class Ifi
int ofthen(int n)
if(0)
if_zero(0)
isit = 42
else
maybenot = 667
@ -8,23 +8,23 @@ class Ifi
end
end
-- -- --
s(:expressions,
s(:statements,
s(:class, :Ifi,
s(:derives, nil),
s(:expressions,
s(:function, :int,
s(:statements,
s(:function, :Integer,
s(:name, :ofthen),
s(:parameters,
s(:parameter, :int, :n)),
s(:expressions,
s(:if,
s(:parameter, :Integer, :n)),
s(:statements,
s(:if_statement, :zero,
s(:condition,
s(:int, 0)),
s(:if_true,
s(:assign,
s(:true_statements,
s(:assignment,
s(:name, :isit),
s(:int, 42))),
s(:if_false,
s(:assign,
s(:false_statements,
s(:assignment,
s(:name, :maybenot),
s(:int, 667)))))))))

View File

@ -0,0 +1,16 @@
class Foo < Object
int test()
return 43
end
end
-- -- --
s(:statements,
s(:class, :Foo,
s(:derives, :Object),
s(:statements,
s(:function, :Integer,
s(:name, :test),
s(:parameters),
s(:statements,
s(:return,
s(:int, 43)))))))

View File

@ -0,0 +1,23 @@
class Opers
int foo(int x)
int abba = 5
return abba + 5
end
end
-- -- --
s(:statements,
s(:class, :Opers,
s(:derives, nil),
s(:statements,
s(:function, :Integer,
s(:name, :foo),
s(:parameters,
s(:parameter, :Integer, :x)),
s(:statements,
s(:field_def, :Integer,
s(:name, :abba),
s(:int, 5)),
s(:return,
s(:operator_value, :+,
s(:name, :abba),
s(:int, 5))))))))

View File

@ -0,0 +1,9 @@
class Foo
field int x
end
-- -- --
s(:statements,
s(:class, :Foo,
s(:derives, nil),
s(:statements,
s(:class_field, :Integer, :x))))

View File

@ -1,6 +0,0 @@
[42, foo]
-- -- --
s(:expressions,
s(:array,
s(:int, 42),
s(:name, :foo)))

View File

@ -1,11 +0,0 @@
[ 3 + 4 , foo(22) ]
-- -- --
s(:expressions,
s(:array,
s(:operator, "+",
s(:int, 3),
s(:int, 4)),
s(:call,
s(:name, :foo),
s(:arguments,
s(:int, 22)))))

View File

@ -1,7 +0,0 @@
{ foo => 33 }
-- -- --
s(:expressions,
s(:hash,
s(:assoc,
s(:name, :foo),
s(:int, 33))))

View File

@ -1,7 +0,0 @@
{ foo => true }
-- -- --
s(:expressions,
s(:hash,
s(:assoc,
s(:name, :foo),
s(:true))))

View File

@ -1,10 +0,0 @@
{foo => 33 , bar => 42}
-- -- --
s(:expressions,
s(:hash,
s(:assoc,
s(:name, :foo),
s(:int, 33)),
s(:assoc,
s(:name, :bar),
s(:int, 42))))

View File

@ -1,5 +0,0 @@
[42]
-- -- --
s(:expressions,
s(:array,
s(:int, 42)))

View File

@ -1,14 +0,0 @@
if(0)
42
else
667
end
-- -- --
s(:expressions,
s(:if,
s(:condition,
s(:int, 0)),
s(:if_true,
s(:int, 42)),
s(:if_false,
s(:int, 667))))

View File

@ -1,25 +0,0 @@
if(3 > var)
Object.initialize(3)
else
var.new(33)
end
-- -- --
s(:expressions,
s(:if,
s(:condition,
s(:operator, ">",
s(:int, 3),
s(:name, :var))),
s(:if_true,
s(:call,
s(:name, :initialize),
s(:arguments,
s(:int, 3)),
s(:receiver,
s(:module, "Object")))),
s(:if_false, s(:call,
s(:name, :new),
s(:arguments,
s(:int, 33)),
s(:receiver,
s(:name, :var))))))

View File

@ -1,11 +0,0 @@
if(0)
42
end
-- -- --
s(:expressions,
s(:if,
s(:condition,
s(:int, 0)),
s(:if_true,
s(:int, 42)),
s(:if_false, nil)))

View File

@ -1,18 +0,0 @@
if(3 > var)
Object.initialize(3)
end
-- -- --
s(:expressions,
s(:if,
s(:condition,
s(:operator, ">",
s(:int, 3),
s(:name, :var))),
s(:if_true,
s(:call,
s(:name, :initialize),
s(:arguments,
s(:int, 3)),
s(:receiver,
s(:module, "Object")))),
s(:if_false, nil)))

View File

@ -1,6 +0,0 @@
a = 5
-- -- --
s(:expressions,
s(:assign,
s(:name, :a),
s(:int, 5)))

View File

@ -1,6 +0,0 @@
a = 5
-- -- --
s(:expressions,
s(:assign,
s(:name, :a),
s(:int, 5)))

View File

@ -1,6 +0,0 @@
a - b
-- -- --
s(:expressions,
s(:operator, "-",
s(:name, :a),
s(:name, :b)))

View File

@ -1,6 +0,0 @@
a - 5
-- -- --
s(:expressions,
s(:operator, "-",
s(:name, :a),
s(:int, 5)))

View File

@ -1,6 +0,0 @@
a - "st"
-- -- --
s(:expressions,
s(:operator, "-",
s(:name, :a),
s(:string, "st")))

View File

@ -1,6 +0,0 @@
a == true
-- -- --
s(:expressions,
s(:operator, "==",
s(:name, :a),
s(:true)))

View File

@ -1,6 +0,0 @@
5 / 3
-- -- --
s(:expressions,
s(:operator, "/",
s(:int, 5),
s(:int, 3)))

View File

@ -1,6 +0,0 @@
5 > 3
-- -- --
s(:expressions,
s(:operator, ">",
s(:int, 5),
s(:int, 3)))

View File

@ -1,6 +0,0 @@
5 - 3
-- -- --
s(:expressions,
s(:operator, "-",
s(:int, 5),
s(:int, 3)))

View File

@ -1,6 +0,0 @@
5 * 3
-- -- --
s(:expressions,
s(:operator, "*",
s(:int, 5),
s(:int, 3)))

View File

@ -1,6 +0,0 @@
5 + 3
-- -- --
s(:expressions,
s(:operator, "+",
s(:int, 5),
s(:int, 3)))

View File

@ -1,6 +0,0 @@
5 < 3
-- -- --
s(:expressions,
s(:operator, "<",
s(:int, 5),
s(:int, 3)))

View File

@ -1,8 +0,0 @@
2 + 3 * 4
-- -- --
s(:expressions,
s(:operator, "+",
s(:int, 2),
s(:operator, "*",
s(:int, 3),
s(:int, 4))))

View File

@ -1,8 +0,0 @@
2 * 3 + 4
-- -- --
s(:expressions,
s(:operator, "+",
s(:operator, "*",
s(:int, 2),
s(:int, 3)),
s(:int, 4)))

View File

@ -1,8 +0,0 @@
2 + 3 + 4
-- -- --
s(:expressions,
s(:operator, "+",
s(:operator, "+",
s(:int, 2),
s(:int, 3)),
s(:int, 4)))

View File

@ -0,0 +1,7 @@
foo.bar
-- -- --
s(:field_access,
s(:receiver,
s(:name, :foo)),
s(:field,
s(:name, :bar)))

View File

@ -1,12 +1,13 @@
int self.length( ref x )
length
int self.length( Object x )
return 5
end
-- -- --
s(:expressions,
s(:function, :int,
s(:statements,
s(:function, :Integer,
s(:name, :length),
s(:parameters,
s(:parameter, :ref, :x)),
s(:expressions,
s(:name, :length)),
s(:parameter, :Object, :x)),
s(:statements,
s(:return,
s(:int, 5))),
s(:receiver, :self)))

View File

@ -1,7 +1,7 @@
int fibonaccit(int n)
a = 0
b = 1
while( n > 1 )
while_positive( n )
tmp = a
a = b
b = tmp + b
@ -10,41 +10,39 @@ int fibonaccit(int n)
end
end
-- -- --
s(:expressions,
s(:function, :int,
s(:statements,
s(:function, :Integer,
s(:name, :fibonaccit),
s(:parameters,
s(:parameter, :int, :n)),
s(:expressions,
s(:assign,
s(:parameter, :Integer, :n)),
s(:statements,
s(:assignment,
s(:name, :a),
s(:int, 0)),
s(:assign,
s(:assignment,
s(:name, :b),
s(:int, 1)),
s(:while,
s(:condition,
s(:operator, ">",
s(:name, :n),
s(:int, 1))),
s(:expressions,
s(:assign,
s(:while_statement, :positive,
s(:conditional,
s(:name, :n)),
s(:statements,
s(:assignment,
s(:name, :tmp),
s(:name, :a)),
s(:assign,
s(:assignment,
s(:name, :a),
s(:name, :b)),
s(:assign,
s(:assignment,
s(:name, :b),
s(:operator, "+",
s(:operator_value, :+,
s(:name, :tmp),
s(:name, :b))),
s(:call,
s(:name, :puts),
s(:arguments,
s(:name, :b))),
s(:assign,
s(:assignment,
s(:name, :n),
s(:operator, "-",
s(:operator_value, :-,
s(:name, :n),
s(:int, 1))))))))

View File

@ -2,21 +2,15 @@ int foo(int x)
int a = 5
return a
end
3.foo( 4 )
-- -- --
s(:expressions,
s(:function, :int,
s(:statements,
s(:function, :Integer,
s(:name, :foo),
s(:parameters,
s(:parameter, :int, :x)),
s(:expressions,
s(:field_def, :int, :a,
s(:parameter, :Integer, :x)),
s(:statements,
s(:field_def, :Integer,
s(:name, :a),
s(:int, 5)),
s(:return,
s(:name, :a)))),
s(:call,
s(:name, :foo),
s(:arguments,
s(:int, 4)),
s(:receiver,
s(:int, 3))))
s(:name, :a)))))

View File

@ -1,25 +1,25 @@
ref ofthen(int n)
if(0)
int ofthen(int n)
if_plus(0)
isit = 42
else
maybenot = 667
end
end
-- -- --
s(:expressions,
s(:function, :ref,
s(:statements,
s(:function, :Integer,
s(:name, :ofthen),
s(:parameters,
s(:parameter, :int, :n)),
s(:expressions,
s(:if,
s(:parameter, :Integer, :n)),
s(:statements,
s(:if_statement, :plus,
s(:condition,
s(:int, 0)),
s(:if_true,
s(:assign,
s(:true_statements,
s(:assignment,
s(:name, :isit),
s(:int, 42))),
s(:if_false,
s(:assign,
s(:false_statements,
s(:assignment,
s(:name, :maybenot),
s(:int, 667)))))))

View File

@ -1,10 +1,11 @@
int foo()
5
return 5
end
-- -- --
s(:expressions,
s(:function, :int,
s(:name, :foo),
s(:statements,
s(:function, :Integer,
s(:name, :foo),
s(:parameters),
s(:expressions,
s(:int, 5))))
s(:statements,
s(:return,
s(:int, 5)))))

View File

@ -1,16 +1,19 @@
int foo(int x)
int abba = 5
abba + 5
abba = abba + 5
end
-- -- --
s(:expressions,
s(:function, :int,
s(:statements,
s(:function, :Integer,
s(:name, :foo),
s(:parameters,
s(:parameter, :int, :x)),
s(:expressions,
s(:field_def, :int, :abba,
s(:int, 5)),
s(:operator, "+",
s(:parameter, :Integer, :x)),
s(:statements,
s(:field_def, :Integer,
s(:name, :abba),
s(:int, 5)))))
s(:int, 5)),
s(:assignment,
s(:name, :abba),
s(:operator_value, :+,
s(:name, :abba),
s(:int, 5))))))

View File

@ -1,15 +1,16 @@
int retvar(ref n)
int retvar(Object n)
int i = n.layout
return i
end
-- -- --
s(:expressions,
s(:function, :int,
s(:statements,
s(:function, :Integer,
s(:name, :retvar),
s(:parameters,
s(:parameter, :ref, :n)),
s(:expressions,
s(:field_def, :int, :i,
s(:parameter, :Object, :n)),
s(:statements,
s(:field_def, :Integer,
s(:name, :i),
s(:field_access,
s(:receiver,
s(:name, :n)),

View File

@ -1,25 +1,25 @@
int retvar(int n)
if( n > 5)
if_positive( n - 5)
return 10
else
return 20
end
end
-- -- --
s(:expressions,
s(:function, :int,
s(:statements,
s(:function, :Integer,
s(:name, :retvar),
s(:parameters,
s(:parameter, :int, :n)),
s(:expressions,
s(:if,
s(:parameter, :Integer, :n)),
s(:statements,
s(:if_statement, :positive,
s(:condition,
s(:operator, ">",
s(:operator_value, :-,
s(:name, :n),
s(:int, 5))),
s(:if_true,
s(:true_statements,
s(:return,
s(:int, 10))),
s(:if_false,
s(:false_statements,
s(:return,
s(:int, 20)))))))

View File

@ -1,25 +1,25 @@
int retvar(int n )
while( n > 5)
while_positive( n - 5)
n = n + 1
return n
end
end
-- -- --
s(:expressions,
s(:function, :int,
s(:statements,
s(:function, :Integer,
s(:name, :retvar),
s(:parameters,
s(:parameter, :int, :n)),
s(:expressions,
s(:while,
s(:condition,
s(:operator, ">",
s(:parameter, :Integer, :n)),
s(:statements,
s(:while_statement, :positive,
s(:conditional,
s(:operator_value, :-,
s(:name, :n),
s(:int, 5))),
s(:expressions,
s(:assign,
s(:statements,
s(:assignment,
s(:name, :n),
s(:operator, "+",
s(:operator_value, :+,
s(:name, :n),
s(:int, 1))),
s(:return,

View File

@ -1,12 +1,13 @@
int foo( int n ,ref m)
n
int foo( int n ,String m)
return n
end
-- -- --
s(:expressions,
s(:function, :int,
s(:statements,
s(:function, :Integer,
s(:name, :foo),
s(:parameters,
s(:parameter, :int, :n),
s(:parameter, :ref, :m)),
s(:expressions,
s(:name, :n))))
s(:parameter, :Integer, :n),
s(:parameter, :String, :m)),
s(:statements,
s(:return,
s(:name, :n)))))

View File

@ -1,29 +1,29 @@
ref fibonaccit(int n)
Biggie fibonaccit(int n)
a = 0
while(n)
while_ok(n)
some = 43
other = some * 4
end
end
-- -- --
s(:expressions,
s(:function, :ref,
s(:statements,
s(:function, :Biggie,
s(:name, :fibonaccit),
s(:parameters,
s(:parameter, :int, :n)),
s(:expressions,
s(:assign,
s(:parameter, :Integer, :n)),
s(:statements,
s(:assignment,
s(:name, :a),
s(:int, 0)),
s(:while,
s(:condition,
s(:while_statement, :ok,
s(:conditional,
s(:name, :n)),
s(:expressions,
s(:assign,
s(:statements,
s(:assignment,
s(:name, :some),
s(:int, 43)),
s(:assign,
s(:assignment,
s(:name, :other),
s(:operator, "*",
s(:operator_value, :*,
s(:name, :some),
s(:int, 4))))))))

View File

@ -1,11 +1,13 @@
int foo(ref x)
5
int foo(Class x)
a = 1
end
-- -- --
s(:expressions,
s(:function, :int,
s(:statements,
s(:function, :Integer,
s(:name, :foo),
s(:parameters,
s(:parameter, :ref, :x)),
s(:expressions,
s(:int, 5))))
s(:parameter, :Class, :x)),
s(:statements,
s(:assignment,
s(:name, :a),
s(:int, 1)))))

View File

@ -0,0 +1,17 @@
if_true(0)
fourty = 10
else
twenty = 5
end
-- -- --
s(:if_statement, :true,
s(:condition,
s(:int, 0)),
s(:true_statements,
s(:assignment,
s(:name, :fourty),
s(:int, 10))),
s(:false_statements,
s(:assignment,
s(:name, :twenty),
s(:int, 5))))

View File

@ -0,0 +1,25 @@
if_yes(3 > var)
Object.initialize(3)
else
var.new(33)
end
-- -- --
s(:if_statement, :yes,
s(:condition,
s(:operator_value, :>,
s(:int, 3),
s(:name, :var))),
s(:true_statements,
s(:call,
s(:name, :initialize),
s(:arguments,
s(:int, 3)),
s(:receiver,
s(:class_name, :Object)))),
s(:false_statements,
s(:call,
s(:name, :new),
s(:arguments,
s(:int, 33)),
s(:receiver,
s(:name, :var)))))

View File

@ -1,11 +0,0 @@
module Opers
field int abba = 5
field ref baab
end
-- -- --
s(:expressions,
s(:module, :Opers,
s(:expressions,
s(:class_field, :int, :abba,
s(:int, 5)),
s(:class_field, :ref, :baab))))

View File

@ -1,17 +0,0 @@
module Foo
class Bar
funcall(3 , var)
end
end
-- -- --
s(:expressions,
s(:module, :Foo,
s(:expressions,
s(:class, :Bar,
s(:derives, nil),
s(:expressions,
s(:call,
s(:name, :funcall),
s(:arguments,
s(:int, 3),
s(:name, :var))))))))

View File

@ -1,23 +0,0 @@
module Soho
ofthen(3 , var)
int ofthen(int n,ref m )
return 44
end
end
-- -- --
s(:expressions,
s(:module, :Soho,
s(:expressions,
s(:call,
s(:name, :ofthen),
s(:arguments,
s(:int, 3),
s(:name, :var))),
s(:function, :int,
s(:name, :ofthen),
s(:parameters,
s(:parameter, :int, :n),
s(:parameter, :ref, :m)),
s(:expressions,
s(:return,
s(:int, 44)))))))

View File

@ -1,29 +0,0 @@
module Foo
ref ofthen(int n)
if(0)
isit = 42
else
maybenot = 667
end
end
end
-- -- --
s(:expressions,
s(:module, :Foo,
s(:expressions,
s(:function, :ref,
s(:name, :ofthen),
s(:parameters,
s(:parameter, :int, :n)),
s(:expressions,
s(:if,
s(:condition,
s(:int, 0)),
s(:if_true,
s(:assign,
s(:name, :isit),
s(:int, 42))),
s(:if_false,
s(:assign,
s(:name, :maybenot),
s(:int, 667)))))))))

View File

@ -1,25 +0,0 @@
module Opers
int foo(int x)
int abba = self.index
return abba + 5
end
end
-- -- --
s(:expressions,
s(:module, :Opers,
s(:expressions,
s(:function, :int,
s(:name, :foo),
s(:parameters,
s(:parameter, :int, :x)),
s(:expressions,
s(:field_def, :int, :abba,
s(:field_access,
s(:receiver,
s(:name, :self)),
s(:field,
s(:name, :index)))),
s(:return,
s(:operator, "+",
s(:name, :abba),
s(:int, 5))))))))

View File

@ -1,8 +0,0 @@
module Simple
5
end
-- -- --
s(:expressions,
s(:module, :Simple,
s(:expressions,
s(:int, 5))))

View File

@ -0,0 +1,9 @@
foo.bar - gumbar
-- -- --
s(:operator_value, :-,
s(:field_access,
s(:receiver,
s(:name, :foo)),
s(:field,
s(:name, :bar))),
s(:name, :gumbar))

View File

@ -0,0 +1,9 @@
5 % foo.bar
-- -- --
s(:operator_value, :%,
s(:int, 5),
s(:field_access,
s(:receiver,
s(:name, :foo)),
s(:field,
s(:name, :bar))))

View File

@ -0,0 +1,5 @@
3 > var
-- -- --
s(:operator_value, :>,
s(:int, 3),
s(:name, :var))

View File

@ -0,0 +1,5 @@
5 + 7
-- -- --
s(:operator_value, :+,
s(:int, 5),
s(:int, 7))

View File

@ -0,0 +1,5 @@
a - b
-- -- --
s(:operator_value, :-,
s(:name, :a),
s(:name, :b))

View File

@ -0,0 +1,5 @@
a - 5
-- -- --
s(:operator_value, :-,
s(:name, :a),
s(:int, 5))

View File

@ -0,0 +1,5 @@
a - "st"
-- -- --
s(:operator_value, :-,
s(:name, :a),
s(:string, "st"))

View File

@ -0,0 +1,5 @@
a == true
-- -- --
s(:operator_value, :==,
s(:name, :a),
s(:true))

View File

@ -0,0 +1,5 @@
5 / 3
-- -- --
s(:operator_value, :/,
s(:int, 5),
s(:int, 3))

View File

@ -0,0 +1,5 @@
5 > 3
-- -- --
s(:operator_value, :>,
s(:int, 5),
s(:int, 3))

View File

@ -0,0 +1,5 @@
5 - 3
-- -- --
s(:operator_value, :-,
s(:int, 5),
s(:int, 3))

View File

@ -0,0 +1,5 @@
5 * 3
-- -- --
s(:operator_value, :*,
s(:int, 5),
s(:int, 3))

View File

@ -0,0 +1,5 @@
5 + 3
-- -- --
s(:operator_value, :+,
s(:int, 5),
s(:int, 3))

View File

@ -0,0 +1,5 @@
5 < 3
-- -- --
s(:operator_value, :<,
s(:int, 5),
s(:int, 3))

View File

@ -0,0 +1,9 @@
gumbar & foo.bar
-- -- --
s(:operator_value, :&,
s(:name, :gumbar),
s(:field_access,
s(:receiver,
s(:name, :foo)),
s(:field,
s(:name, :bar))))

View File

@ -0,0 +1,5 @@
bar - gumbar
-- -- --
s(:operator_value, :-,
s(:name, :bar),
s(:name, :gumbar))

View File

@ -1,5 +0,0 @@
return 42
-- -- --
s(:expressions,
s(:return,
s(:int, 42)))

View File

@ -1,5 +0,0 @@
return "hello"
-- -- --
s(:expressions,
s(:return,
s(:string, "hello")))

View File

@ -1,5 +0,0 @@
return foo
-- -- --
s(:expressions,
s(:return,
s(:name, :foo)))

View File

@ -0,0 +1,4 @@
return 42
-- -- --
s(:return,
s(:int, 42))

View File

@ -0,0 +1,4 @@
return "hello"
-- -- --
s(:return,
s(:string, "hello"))

View File

@ -0,0 +1,4 @@
return foo
-- -- --
s(:return,
s(:name, :foo))

View File

@ -1,15 +1,21 @@
class FooBo
Bar.call(35)
int main()
Bar.call(35)
end
end
-- -- --
s(:expressions,
s(:statements,
s(:class, :FooBo,
s(:derives, nil),
s(:expressions,
s(:call,
s(:name, :call),
s(:arguments,
s(:int, 35)),
s(:receiver,
s(:module, "Bar"))))))
s(:statements,
s(:function, :Integer,
s(:name, :main),
s(:parameters),
s(:statements,
s(:call,
s(:name, :call),
s(:arguments,
s(:int, 35)),
s(:receiver,
s(:class_name, :Bar))))))))

View File

@ -1,19 +1,34 @@
int foo(ref x)
a = 5
class Object
int foo(String x)
a = 5
end
end
class Other < Object
int foo()
foo( 3 )
end
end
foo( 3 )
-- -- --
s(:expressions,
s(:function, :int,
s(:name, :foo),
s(:parameters,
s(:parameter, :ref, :x)),
s(:expressions,
s(:assign,
s(:name, :a),
s(:int, 5)))),
s(:call,
s(:name, :foo),
s(:arguments,
s(:int, 3))))
s(:statements,
s(:class, :Object,
s(:derives, nil),
s(:statements,
s(:function, :Integer,
s(:name, :foo),
s(:parameters,
s(:parameter, :String, :x)),
s(:statements,
s(:assignment,
s(:name, :a),
s(:int, 5)))))),
s(:class, :Other,
s(:derives, :Object),
s(:statements,
s(:function, :Integer,
s(:name, :foo),
s(:parameters),
s(:statements,
s(:call,
s(:name, :foo),
s(:arguments,
s(:int, 3))))))))

View File

@ -1,56 +1,65 @@
int fibonaccit(int n)
a = 0
b = 1
while( n > 1 )
tmp = a
a = b
b = tmp + b
puts(b)
n = n - 1
class Object
int fibonaccit(int n)
a = 0
b = 1
while_plus( n )
tmp = a
a = b
b = tmp + b
puts(b)
n = n - 1
end
end
int main()
fibonaccit( 10 )
end
end
fibonaccit( 10 )
-- -- --
s(:expressions,
s(:function, :int,
s(:name, :fibonaccit),
s(:parameters,
s(:parameter, :int, :n)),
s(:expressions,
s(:assign,
s(:name, :a),
s(:int, 0)),
s(:assign,
s(:name, :b),
s(:int, 1)),
s(:while,
s(:condition,
s(:operator, ">",
s(:name, :n),
s(:int, 1))),
s(:expressions,
s(:assign,
s(:name, :tmp),
s(:name, :a)),
s(:assign,
s(:statements,
s(:class, :Object,
s(:derives, nil),
s(:statements,
s(:function, :Integer,
s(:name, :fibonaccit),
s(:parameters,
s(:parameter, :Integer, :n)),
s(:statements,
s(:assignment,
s(:name, :a),
s(:name, :b)),
s(:assign,
s(:int, 0)),
s(:assignment,
s(:name, :b),
s(:operator, "+",
s(:name, :tmp),
s(:name, :b))),
s(:int, 1)),
s(:while_statement, :plus,
s(:conditional,
s(:name, :n)),
s(:statements,
s(:assignment,
s(:name, :tmp),
s(:name, :a)),
s(:assignment,
s(:name, :a),
s(:name, :b)),
s(:assignment,
s(:name, :b),
s(:operator_value, :+,
s(:name, :tmp),
s(:name, :b))),
s(:call,
s(:name, :puts),
s(:arguments,
s(:name, :b))),
s(:assignment,
s(:name, :n),
s(:operator_value, :-,
s(:name, :n),
s(:int, 1))))))),
s(:function, :Integer,
s(:name, :main),
s(:parameters),
s(:statements,
s(:call,
s(:name, :puts),
s(:name, :fibonaccit),
s(:arguments,
s(:name, :b))),
s(:assign,
s(:name, :n),
s(:operator, "-",
s(:name, :n),
s(:int, 1))))))),
s(:call,
s(:name, :fibonaccit),
s(:arguments,
s(:int, 10))))
s(:int, 10))))))))

View File

@ -1,20 +0,0 @@
module Fibo
a = 5 + foo
bar( b , a , r)
end
-- -- --
s(:expressions,
s(:module, :Fibo,
s(:expressions,
s(:assign,
s(:name, :a),
s(:operator, "+",
s(:int, 5),
s(:name, :foo))),
s(:call,
s(:name, :bar),
s(:arguments,
s(:name, :b),
s(:name, :a),
s(:name, :r))))))

View File

@ -1,26 +0,0 @@
module Fibo
int fibonaccit(int n)
int a = 0
return a
end
fibonaccit( 10 )
end
-- -- --
s(:expressions,
s(:module, :Fibo,
s(:expressions,
s(:function, :int,
s(:name, :fibonaccit),
s(:parameters,
s(:parameter, :int, :n)),
s(:expressions,
s(:field_def, :int, :a,
s(:int, 0)),
s(:return,
s(:name, :a)))),
s(:call,
s(:name, :fibonaccit),
s(:arguments,
s(:int, 10))))))

View File

@ -1,18 +0,0 @@
module FooBo
class Bar
a = 5 + foo
end
end
-- -- --
s(:expressions,
s(:module, :FooBo,
s(:expressions,
s(:class, :Bar,
s(:derives, nil),
s(:expressions,
s(:assign,
s(:name, :a),
s(:operator, "+",
s(:int, 5),
s(:name, :foo))))))))

View File

@ -0,0 +1,12 @@
if_zero(0)
four = 42
end
-- -- --
s(:if_statement, :zero,
s(:condition,
s(:int, 0)),
s(:true_statements,
s(:assignment,
s(:name, :four),
s(:int, 42))),
s(:false_statements, nil))

View File

@ -0,0 +1,17 @@
if_overflow(3 + 100000 )
Object.initialize(3)
end
-- -- --
s(:if_statement, :overflow,
s(:condition,
s(:operator_value, :+,
s(:int, 3),
s(:int, 100000))),
s(:true_statements,
s(:call,
s(:name, :initialize),
s(:arguments,
s(:int, 3)),
s(:receiver,
s(:class_name, :Object)))),
s(:false_statements, nil))

View File

@ -1,35 +0,0 @@
while( n > 1)
tmp = a
a = b
b = tmp + b
puts(b)
n = n - 1
end
-- -- --
s(:expressions,
s(:while,
s(:condition,
s(:operator, ">",
s(:name, :n),
s(:int, 1))),
s(:expressions,
s(:assign,
s(:name, :tmp),
s(:name, :a)),
s(:assign,
s(:name, :a),
s(:name, :b)),
s(:assign,
s(:name, :b),
s(:operator, "+",
s(:name, :tmp),
s(:name, :b))),
s(:call,
s(:name, :puts),
s(:arguments,
s(:name, :b))),
s(:assign,
s(:name, :n),
s(:operator, "-",
s(:name, :n),
s(:int, 1))))))

View File

@ -1,17 +0,0 @@
while(1)
tmp = a
puts(b)
end
-- -- --
s(:expressions,
s(:while,
s(:condition,
s(:int, 1)),
s(:expressions,
s(:assign,
s(:name, :tmp),
s(:name, :a)),
s(:call,
s(:name, :puts),
s(:arguments,
s(:name, :b))))))

View File

@ -1,23 +0,0 @@
while(1)
tmp = String.new()
tmp.puts(i)
end
-- -- --
s(:expressions,
s(:while,
s(:condition,
s(:int, 1)),
s(:expressions,
s(:assign,
s(:name, :tmp),
s(:call,
s(:name, :new),
s(:arguments),
s(:receiver,
s(:module, "String")))),
s(:call,
s(:name, :puts),
s(:arguments,
s(:name, :i)),
s(:receiver,
s(:name, :tmp))))))

View File

@ -0,0 +1,34 @@
while_allgood( n > 1)
tmp = a
a = b
b = tmp + b
puts(b)
n = n - 1
end
-- -- --
s(:while_statement, :allgood,
s(:conditional,
s(:operator_value, :>,
s(:name, :n),
s(:int, 1))),
s(:statements,
s(:assignment,
s(:name, :tmp),
s(:name, :a)),
s(:assignment,
s(:name, :a),
s(:name, :b)),
s(:assignment,
s(:name, :b),
s(:operator_value, :+,
s(:name, :tmp),
s(:name, :b))),
s(:call,
s(:name, :puts),
s(:arguments,
s(:name, :b))),
s(:assignment,
s(:name, :n),
s(:operator_value, :-,
s(:name, :n),
s(:int, 1)))))

View File

@ -0,0 +1,16 @@
while_false(1)
tmp = a
puts(b)
end
-- -- --
s(:while_statement, :false,
s(:conditional,
s(:int, 1)),
s(:statements,
s(:assignment,
s(:name, :tmp),
s(:name, :a)),
s(:call,
s(:name, :puts),
s(:arguments,
s(:name, :b)))))

View File

@ -0,0 +1,22 @@
while_true(1)
tmp = String.new()
tmp.puts(i)
end
-- -- --
s(:while_statement, :true,
s(:conditional,
s(:int, 1)),
s(:statements,
s(:assignment,
s(:name, :tmp),
s(:call,
s(:name, :new),
s(:arguments),
s(:receiver,
s(:class_name, :String)))),
s(:call,
s(:name, :puts),
s(:arguments,
s(:name, :i)),
s(:receiver,
s(:name, :tmp)))))

View File

@ -8,7 +8,7 @@ module ParserHelper
def self.included(base)
base.send :include, InstanceMethods #provides helpers and setup
base.send :include, AST::if_true
base.send :include, AST::true_statements
base.send :extend, ClassMethods #gets the method creation going
end

View File

@ -13,7 +13,7 @@ if ENV['CODECLIMATE_REPO_TOKEN']
CodeClimate::TestReporter.start
end
require 'salama-reader'
require 'soml-parser'
require "minitest"
require "minitest/autorun"

View File

@ -10,7 +10,13 @@ class TestAll < MiniTest::Test
def check_file file
inn , out = File.new(file).read.split(SEPERATOR)
sexp = eval(out)
syntax = Parser::Salama.new.parse_with_debug(inn)
begin
syntax = Parser::Salama.new.parse(inn)
rescue
root = file.split("/")[2]
parser = Parser::Salama.new.send root.to_sym
syntax = parser.parse_with_debug(inn )
end
result = Parser::Transform.new.apply(syntax)
equal = (sexp == result)
unless equal
@ -28,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

36
to_code.rb Normal file
View File

@ -0,0 +1,36 @@
require 'rubygems'
require 'bundler'
Bundler.setup(:default, :development)
require 'soml-parser'
require "parslet/convenience"
require "ast/sexp"
require "pp"
class Converter
include AST::Sexp
SEPERATOR = "-- -- --"
def to_ast
file = ARGV[0]
inn = File.new(file).read.split(SEPERATOR).first
begin
syntax = Parser::Salama.new.parse(inn)
rescue
root = file.split("/").last.split(".").first
parser = Parser::Salama.new.send root.to_sym
syntax = parser.parse_with_debug(inn )
end
result = Parser::Transform.new.apply(syntax)
out_file = File.new(file, "w")
out_file.puts inn
out_file.puts SEPERATOR
out_file.puts result.inspect
out_file.close
end
end
Converter.new.to_ast