27 Commits

Author SHA1 Message Date
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
148 changed files with 909 additions and 1133 deletions

View File

@ -2,7 +2,7 @@ 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
@ -13,5 +13,4 @@ gem "salama-reader" , :path => "."
group :development do
gem "codeclimate-test-reporter", require: nil
gem "minitest"
gem "rubygems-tasks"
end

View File

@ -8,9 +8,9 @@ GIT
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 +24,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 +38,7 @@ DEPENDENCIES
codeclimate-test-reporter
minitest
rake
rubygems-tasks
salama-reader!
soml-parser!
BUNDLED WITH
1.10.6

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))
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,4 @@
require 'parslet'
require 'parser/salama'
require 'parser/soml'
require "ast"
require 'parser/transform'

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

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

View File

@ -0,0 +1,10 @@
[ 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))))

View File

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

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(: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(:name, :foo)))

View File

@ -1,7 +1,6 @@
puts( "hello")
-- -- --
s(:expressions,
s(:call,
s(:name, :puts),
s(:arguments,
s(:string, "hello"))))
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(:int, 42)))

View File

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

View File

@ -1,7 +1,6 @@
foo(42)
-- -- --
s(:expressions,
s(:call,
s(:name, :foo),
s(:arguments,
s(:int, 42))))
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(: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(: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(: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(: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(: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,6 @@
{ foo => 33 }
-- -- --
s(:hash,
s(:assoc,
s(:name, :foo),
s(:int, 33)))

View File

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

View File

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

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
int main()
Bar.call(35)
end
end
-- -- --
s(:expressions,
s(:statements,
s(:class, :FooBo,
s(:derives, nil),
s(:expressions,
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(:module, "Bar"))))))
s(:class_name, :Bar))))))))

View File

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

View File

@ -1,7 +1,8 @@
class Object
int fibonaccit(int n)
a = 0
b = 1
while( n > 1 )
while_plus( n )
tmp = a
a = b
b = tmp + b
@ -10,47 +11,55 @@ int fibonaccit(int n)
end
end
int main()
fibonaccit( 10 )
end
end
-- -- --
s(:expressions,
s(:function, :int,
s(:statements,
s(:class, :Object,
s(:derives, nil),
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, :plus,
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))))))),
s(:function, :Integer,
s(:name, :main),
s(:parameters),
s(:statements,
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