zunscript 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +100 -0
- data/Rakefile +9 -0
- data/bin/setup +5 -0
- data/bin/zsi +35 -0
- data/examples/test.zun +105 -0
- data/ext/zunscript/Makefile +9 -0
- data/ext/zunscript/ZunScript.g +87 -0
- data/ext/zunscript/antlr4ruby +106 -0
- data/ext/zunscript/ext.rb +2 -0
- data/ext/zunscript/extconf.rb +0 -0
- data/ext/zunscript/lexer.rb +1240 -0
- data/ext/zunscript/parser.rb +2225 -0
- data/lib/zunscript.rb +3 -0
- data/lib/zunscript/block.rb +72 -0
- data/lib/zunscript/environment.rb +104 -0
- data/lib/zunscript/scope.rb +55 -0
- data/lib/zunscript/value.rb +67 -0
- data/lib/zunscript/version.rb +3 -0
- data/zunscript.gemspec +29 -0
- metadata +141 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f412e1847f8dfeebd98d2488b7f936c636e6bcac
|
4
|
+
data.tar.gz: c5797f7e07ccffc133e5461941ea1c0ec437b495
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a8df68e9a5f1a3efd2d00575a15e938c966e468619e072c88fb55b194901920d7d27de0188212950c2e0af2a015a2837ec4af5ffb62162c05bd41320ee618c2c
|
7
|
+
data.tar.gz: 4ffa9693c87f16a1b7ecb5c2961c5e35979967f0f15b90f8eaaadc7e5b66062c20427458678cce79aad5f0f81d89e74be7f746999fa14b5bd73174620a7d9edc
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 S0lll0s
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
ZunScript
|
2
|
+
=========
|
3
|
+
ZunScript is a conceptual Scripting Language.
|
4
|
+
Below are some loosely-defined syntax rules.
|
5
|
+
I am borrowing and expanding upon concepts of Ruby, Python and Lua.
|
6
|
+
|
7
|
+
The main features I want to explore with ZunScript are method and parameter binding as well as a very monkeypatchable langauge.
|
8
|
+
I am trying to boil everything down to the a few very simple and concise rules and ideas with clear syntax;
|
9
|
+
On a higher level than Lua but not as polluted as Ruby is in my opinion (for example things like `$1, $2, ...` are way too specific to be in a language's core for example).
|
10
|
+
|
11
|
+
I want to eliminate keywords and hardcoded things wherever possible, if possible to the point where control structures are just functions too.
|
12
|
+
|
13
|
+
Property Access
|
14
|
+
---------------
|
15
|
+
You can access an objects raw properties with the `!` symbol:
|
16
|
+
|
17
|
+
object!value # obtain value of object
|
18
|
+
object!method # obtain method of object
|
19
|
+
|
20
|
+
Methods can be bound with the `.` symbol:
|
21
|
+
|
22
|
+
object.method # obtain method of object (bound to object)
|
23
|
+
|
24
|
+
this will return another function that accepts one parameter less and is bound to `object` instead.
|
25
|
+
|
26
|
+
|
27
|
+
Calling
|
28
|
+
-------
|
29
|
+
You can invoke functions with the `!` symbol:
|
30
|
+
|
31
|
+
method!
|
32
|
+
method! 1, 2, 3
|
33
|
+
|
34
|
+
Together with bound/unbound property access you can do various things:
|
35
|
+
|
36
|
+
object = {}
|
37
|
+
def object.trace a, b, c # => function(3)
|
38
|
+
return a, b, c
|
39
|
+
end
|
40
|
+
|
41
|
+
object.trace # => function(2)
|
42
|
+
object!trace # => function(3)
|
43
|
+
|
44
|
+
object.trace! # => <object>, nil, nil
|
45
|
+
object.trace! 1, 2 # => <object>, 1, 2
|
46
|
+
|
47
|
+
object!trace! # => nil, nil, nil
|
48
|
+
object!trace! 1, 2 # => 1, 2, nil
|
49
|
+
|
50
|
+
a = object.trace 1, 2 # => function(0)
|
51
|
+
b = object!trace 1, 2 # => function(1)
|
52
|
+
|
53
|
+
a! # => <object>, 1, 2
|
54
|
+
b! # => 1, 2, nil
|
55
|
+
b! 3 # => 1, 2, 3
|
56
|
+
|
57
|
+
Blocks
|
58
|
+
------
|
59
|
+
Blocks start with `>` and end with `end`:
|
60
|
+
|
61
|
+
do
|
62
|
+
print! "hello"
|
63
|
+
end
|
64
|
+
|
65
|
+
They can accept parmeters after the `>` sign:
|
66
|
+
|
67
|
+
print_block = >a, b
|
68
|
+
print! a, b
|
69
|
+
end
|
70
|
+
|
71
|
+
Blocks can be passed as parameters (as lambdas):
|
72
|
+
|
73
|
+
for 1, 4, >a
|
74
|
+
print! a
|
75
|
+
end
|
76
|
+
|
77
|
+
Single lines can also be passed as blocks:
|
78
|
+
|
79
|
+
just_like_if = <, condition, block
|
80
|
+
if condition, <
|
81
|
+
block!
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
print! "value was true!" < kind_of_if value
|
86
|
+
|
87
|
+
This will:
|
88
|
+
3. bind `value` to `kind_of_if`
|
89
|
+
2. build a Block from `print! "value was true!"
|
90
|
+
1. invoke the bound `kind_of_if` with the Block as a parameter.
|
91
|
+
|
92
|
+
It is synonymous to this piece of code:
|
93
|
+
|
94
|
+
kind_of_if! value, <
|
95
|
+
print! "value was true!"
|
96
|
+
end
|
97
|
+
|
98
|
+
Single-line Block literals can also accept parameters:
|
99
|
+
|
100
|
+
print! a, b <a, b for 1, 4
|
data/Rakefile
ADDED
data/bin/setup
ADDED
data/bin/zsi
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'trollop'
|
4
|
+
require 'colorize'
|
5
|
+
require 'zunscript'
|
6
|
+
|
7
|
+
opts = Trollop::options do
|
8
|
+
version "zsi (c) Sol Bekic 2015"
|
9
|
+
opt :log, "Print per-line results"
|
10
|
+
opt :debug, "Print debug info (AST)"
|
11
|
+
opt :interactive, "Go into interactive mode after running files"
|
12
|
+
end
|
13
|
+
|
14
|
+
e = ZunScript::Environment.new debug: opts[:debug]
|
15
|
+
ARGV.reject! do |file|
|
16
|
+
e.run_script open(file) do |res|
|
17
|
+
puts "[#{n.statement}]\t=> #{res.inspect}".colorize :red if opts[:log]
|
18
|
+
end
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
if opts[:interactive]
|
23
|
+
while true
|
24
|
+
print "zsi > "
|
25
|
+
buffer = ""
|
26
|
+
l = "asd"
|
27
|
+
buffer << gets
|
28
|
+
while not l == "\n"
|
29
|
+
print "... > "
|
30
|
+
l = gets
|
31
|
+
buffer << l
|
32
|
+
end
|
33
|
+
puts "=> #{(e.run_line buffer).inspect}".colorize :blue
|
34
|
+
end
|
35
|
+
end
|
data/examples/test.zun
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
# the Environment currently provides these blocks
|
2
|
+
# print - print all parameters on one line
|
3
|
+
# puts - print every parameter on its own line
|
4
|
+
# add - add two numbers
|
5
|
+
# multiply - multiply two numbers
|
6
|
+
|
7
|
+
## Calling
|
8
|
+
########
|
9
|
+
print! "hello world"
|
10
|
+
print! "one", 2
|
11
|
+
puts!
|
12
|
+
|
13
|
+
## Assignment
|
14
|
+
############
|
15
|
+
x = 2
|
16
|
+
print! "x is ", x
|
17
|
+
x = multiply! x, 2
|
18
|
+
print! "now x is ", x
|
19
|
+
|
20
|
+
## Binding
|
21
|
+
#########
|
22
|
+
times_two = multiply 2
|
23
|
+
print! "two times 4 equals ", times_two! 4
|
24
|
+
|
25
|
+
## nested Calls and Binding
|
26
|
+
##########################
|
27
|
+
print! times_two! 4, "okay?"
|
28
|
+
print! "2 * 3 = ", (multiply! 2, 3), ", no?"
|
29
|
+
|
30
|
+
## Blocks
|
31
|
+
########
|
32
|
+
doubled_sum = > a, b
|
33
|
+
print! "(BLK) a = ", a
|
34
|
+
print! "(BLK) b = ", b
|
35
|
+
times_two! (add! a, b)
|
36
|
+
end
|
37
|
+
|
38
|
+
doubled_sum! 2, 3
|
39
|
+
doubled_sum! 2, 3
|
40
|
+
|
41
|
+
y = >
|
42
|
+
print! "parameterless block"
|
43
|
+
end
|
44
|
+
|
45
|
+
custom_multiply = > a, b
|
46
|
+
print! "a: ", a, ", b: ", b
|
47
|
+
multiply! a, b
|
48
|
+
end
|
49
|
+
custom_double = custom_multiply 2
|
50
|
+
|
51
|
+
print! custom_double! 4, " should be 8"
|
52
|
+
nine = custom_double 4.5
|
53
|
+
print! nine!, " should be 9"
|
54
|
+
|
55
|
+
## lexical Scope
|
56
|
+
################
|
57
|
+
plus_one = add 1
|
58
|
+
|
59
|
+
print! plus_one! 3
|
60
|
+
globally = >
|
61
|
+
plus_one = add 4
|
62
|
+
print! plus_one! 3
|
63
|
+
end
|
64
|
+
locally = >
|
65
|
+
plus_one = add 4
|
66
|
+
print! plus_one! 3
|
67
|
+
end
|
68
|
+
print! plus_one! 3
|
69
|
+
locally!
|
70
|
+
print! plus_one! 3
|
71
|
+
globally!
|
72
|
+
print! plus_one! 3
|
73
|
+
|
74
|
+
## nested Blocks
|
75
|
+
################
|
76
|
+
n_times = > n
|
77
|
+
> x
|
78
|
+
multiply! n, x
|
79
|
+
end
|
80
|
+
end
|
81
|
+
print! "-12 4-"
|
82
|
+
three_times = n_times! 3
|
83
|
+
two_times = n_times! 2
|
84
|
+
print! three_times! 4
|
85
|
+
print! two_times! 2
|
86
|
+
|
87
|
+
## Flow Control
|
88
|
+
###############
|
89
|
+
for! 1, 5, print
|
90
|
+
|
91
|
+
for! 1, 5, > x
|
92
|
+
print! x
|
93
|
+
end
|
94
|
+
|
95
|
+
y = > x
|
96
|
+
print! x, "th time!"
|
97
|
+
end
|
98
|
+
for! 1, 5, y
|
99
|
+
|
100
|
+
## Objects
|
101
|
+
##########
|
102
|
+
#a = Object.new!
|
103
|
+
#a.x = 2
|
104
|
+
#a.y = 1
|
105
|
+
#x.pos.x.y = greg.stuff! a.red
|
@@ -0,0 +1,87 @@
|
|
1
|
+
grammar ZunScript;
|
2
|
+
|
3
|
+
options {
|
4
|
+
language = Ruby;
|
5
|
+
output = AST;
|
6
|
+
backtrack = true;
|
7
|
+
}
|
8
|
+
|
9
|
+
tokens {
|
10
|
+
ASSIGN;
|
11
|
+
INVOKE; BIND;
|
12
|
+
LEFTBLOCK;
|
13
|
+
PARAM;
|
14
|
+
NUM; STR; BLK;
|
15
|
+
VARIABLE;
|
16
|
+
BODY;
|
17
|
+
INDEX;
|
18
|
+
}
|
19
|
+
|
20
|
+
ASSIGN: '=';
|
21
|
+
BLOCK_LEFT: '<';
|
22
|
+
BLOCK_RIGHT: '>';
|
23
|
+
ARITH_SIGN: '+' | '-' | '*' | '/' | '^';
|
24
|
+
BANG: '!';
|
25
|
+
COMMENT: '#';
|
26
|
+
BLOCK_END: 'end';
|
27
|
+
|
28
|
+
COMMA: ',';
|
29
|
+
LPAREN: '(';
|
30
|
+
RPAREN: ')';
|
31
|
+
|
32
|
+
fragment NONCONTROL_CHAR: LETTER | DIGIT | SYMBOL | SPACE;
|
33
|
+
fragment LETTER: LOWER | UPPER;
|
34
|
+
fragment LOWER: 'a'..'z';
|
35
|
+
fragment UPPER: 'A'..'Z';
|
36
|
+
fragment DIGIT: '0'..'9';
|
37
|
+
fragment SYMBOL: '!' | '#'..'/' | ':'..'@' | '['..'`' | '{'..'~';
|
38
|
+
|
39
|
+
fragment FLOAT: INTEGER '.' '0'..'9'+;
|
40
|
+
fragment INTEGER: '0' | '-'? '1'..'9' '0'..'9'*;
|
41
|
+
|
42
|
+
NAME: LETTER (LETTER | DIGIT | '_' | '?')*;
|
43
|
+
STRING: '"' NONCONTROL_CHAR* '"';
|
44
|
+
NUMBER: INTEGER | FLOAT;
|
45
|
+
|
46
|
+
fragment SPACE: ' ' | '\t';
|
47
|
+
NEWLINE: ('\r'? '\n')+;
|
48
|
+
WHITESPACE: SPACE+ { $channel = HIDDEN; };
|
49
|
+
|
50
|
+
script: line* EOF!;
|
51
|
+
line: open_expression? comment!? NEWLINE!;
|
52
|
+
|
53
|
+
comment: COMMENT (~NEWLINE)*;
|
54
|
+
|
55
|
+
open_expression:
|
56
|
+
assign | invoke | bind | closed_expression;
|
57
|
+
closed_expression:
|
58
|
+
value | variable | closed_invoke | closed_bind
|
59
|
+
| LPAREN! open_expression RPAREN!;
|
60
|
+
|
61
|
+
variable: (NAME '.')* NAME -> ^(VARIABLE NAME*);
|
62
|
+
|
63
|
+
value:
|
64
|
+
v=NUMBER -> ^(NUM $v)
|
65
|
+
| v=STRING -> ^(STR $v)
|
66
|
+
| block;
|
67
|
+
|
68
|
+
block: BLOCK_RIGHT arguments NEWLINE block_body BLOCK_END -> ^(BLK arguments* block_body);
|
69
|
+
block_body: line* -> ^(BODY line*);
|
70
|
+
|
71
|
+
arguments: |NAME (COMMA! NAME)*;
|
72
|
+
|
73
|
+
assign:
|
74
|
+
variable ASSIGN open_expression -> ^(ASSIGN variable open_expression);
|
75
|
+
|
76
|
+
invoke:
|
77
|
+
variable BANG params -> ^(INVOKE variable params*);
|
78
|
+
bind:
|
79
|
+
variable params -> ^(BIND variable params*);
|
80
|
+
closed_invoke:
|
81
|
+
variable BANG param? -> ^(INVOKE variable param*);
|
82
|
+
closed_bind:
|
83
|
+
variable param -> ^(BIND variable param);
|
84
|
+
|
85
|
+
params:
|
86
|
+
param (COMMA! param)*;
|
87
|
+
param: closed_expression;
|
@@ -0,0 +1,106 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
=begin LICENSE
|
5
|
+
[The "BSD licence"]
|
6
|
+
Copyright (c) 2009-2011 Kyle Yetter
|
7
|
+
All rights reserved.
|
8
|
+
Redistribution and use in source and binary forms, with or without
|
9
|
+
modification, are permitted provided that the following conditions
|
10
|
+
are met:
|
11
|
+
1. Redistributions of source code must retain the above copyright
|
12
|
+
notice, this list of conditions and the following disclaimer.
|
13
|
+
2. Redistributions in binary form must reproduce the above copyright
|
14
|
+
notice, this list of conditions and the following disclaimer in the
|
15
|
+
documentation and/or other materials provided with the distribution.
|
16
|
+
3. The name of the author may not be used to endorse or promote products
|
17
|
+
derived from this software without specific prior written permission.
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
19
|
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
20
|
+
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
21
|
+
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
22
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
23
|
+
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
24
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
25
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
26
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
27
|
+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
=end
|
29
|
+
|
30
|
+
=begin rdoc antlr4ruby
|
31
|
+
A simple wrapper script to run the ANTLR tool with the ruby antlr3
|
32
|
+
target modifications in place of the default Ruby target data.
|
33
|
+
It essentially does two things:
|
34
|
+
* locate the `customized' ANTLR v.3 JAR archive file
|
35
|
+
* exec the command <tt>java -cp path/to/jar $ARGV</tt>
|
36
|
+
Thus, for ANTLR tool usage, refer to ANTLR's main documentation
|
37
|
+
at http://www.antlr.org .
|
38
|
+
There are a small number of additional options available
|
39
|
+
in addition to ANTLR's options:
|
40
|
+
--version display the Ruby target version and then the
|
41
|
+
ANTLR tool's version information
|
42
|
+
|
43
|
+
--help, -h as ANTLR does not provide these standard switches,
|
44
|
+
it executes the ANTLR tool without arguments to make
|
45
|
+
it print out usage information
|
46
|
+
|
47
|
+
--keep-classpath Do not unset the CLASSPATH environmental variable before
|
48
|
+
executing the java command (*)
|
49
|
+
(*) This script unsets CLASSPATH to avoid interference from system installations
|
50
|
+
of prior versions of ANTLR. The jar that is distributed with this package
|
51
|
+
is complete, and thus does not generally require any external libraries, so
|
52
|
+
this shouldn't cause any major problems. However, if for some reason you
|
53
|
+
need to keep this variable to execute the command properly, you can use
|
54
|
+
the --keep-classpath option.
|
55
|
+
=end
|
56
|
+
|
57
|
+
$0 = 'antlr4ruby'
|
58
|
+
|
59
|
+
begin
|
60
|
+
require 'antlr3'
|
61
|
+
rescue LoadError
|
62
|
+
__DIR__ = File.expand_path( File.dirname __FILE__ )
|
63
|
+
project_top = File.dirname __DIR__
|
64
|
+
lib = File.join( project_top, 'lib' )
|
65
|
+
$LOAD_PATH.unshift( lib )
|
66
|
+
require 'antlr3'
|
67
|
+
end
|
68
|
+
|
69
|
+
jar = ANTLR3.antlr_jar or fail( "cannot find antlr4ruby's customized ANTLR jar" )
|
70
|
+
|
71
|
+
# Convert the Posix path to a proper Windows path, otherwise the Java runtime
|
72
|
+
# will not find the antlr Jar file.
|
73
|
+
# -- Thanks to Marco Soeima for this fix
|
74
|
+
if /cygwin/i =~ RUBY_PLATFORM
|
75
|
+
jar = `cygpath -aw #{jar}`.strip
|
76
|
+
end
|
77
|
+
|
78
|
+
run = proc do | *args |
|
79
|
+
exec( 'java', '-jar', jar, *args )
|
80
|
+
end
|
81
|
+
|
82
|
+
ARGV.delete( '--keep-classpath' ) or
|
83
|
+
ENV.delete( 'CLASSPATH' )
|
84
|
+
|
85
|
+
if ARGV.include?( '--version' )
|
86
|
+
|
87
|
+
puts( "Ruby Target and Runtime Library Version: #{ ANTLR3::VERSION_STRING }" )
|
88
|
+
puts "ANTLR3 Jar Path: #{ jar }"
|
89
|
+
run.call( '-version' )
|
90
|
+
|
91
|
+
elsif ARGV.include?( '--help' ) or ARGV.include?( '-h' )
|
92
|
+
|
93
|
+
# the ANTLR tool doesn't follow the --help/-h convention
|
94
|
+
# -- it provides help only if no arguments are specified
|
95
|
+
run.call
|
96
|
+
|
97
|
+
elsif ARGV.include?( "--jar-path" )
|
98
|
+
|
99
|
+
puts "ANTLR3 Jar Path: #{ jar }"
|
100
|
+
|
101
|
+
else
|
102
|
+
|
103
|
+
# run the tool
|
104
|
+
run.call( *ARGV )
|
105
|
+
|
106
|
+
end
|