zunscript 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|