p-lang 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +38 -8
- data/Rakefile +0 -1
- data/VERSION.yml +3 -3
- data/bin/p-lang +36 -8
- data/lib/p-lang.rb +16 -26
- data/lib/parser/error.rb +32 -0
- data/lib/parser/lexer.rb +245 -0
- data/lib/parser/node.rb +23 -0
- data/lib/parser/syntax_analyser.rb +378 -0
- data/lib/parser/token.rb +19 -0
- data/lib/vm/core/pboolean.rb +27 -0
- data/lib/vm/core/pchar.rb +13 -0
- data/lib/vm/core/pdecimal.rb +130 -0
- data/lib/vm/core/pinteger.rb +125 -0
- data/lib/vm/core/pio.rb +16 -0
- data/lib/vm/core/plist.rb +33 -0
- data/lib/vm/core/pstring.rb +39 -0
- data/lib/vm/environment.rb +67 -42
- data/lib/vm/interpreter.rb +209 -0
- data/lib/vm/pfunctions.rb +46 -0
- data/lib/vm/plambda.rb +42 -0
- data/lib/vm/pobject.rb +44 -42
- data/test/test_lexer +34 -0
- data/test/test_lexer.rb +19 -0
- data/test/test_lexer_tokens +34 -0
- data/test/{test_parser_ok.txt → test_parser} +26 -27
- data/test/test_parser.rb +6 -13
- data/test/test_parser_build +73 -0
- data/test/test_vm +29 -0
- data/test/test_vm.rb +7 -10
- data/test/test_vm_result +29 -0
- metadata +31 -38
- data/bin/teste.p +0 -3
- data/lib/parser/ast.rb +0 -168
- data/lib/parser/nodes.rb +0 -212
- data/lib/parser/p-lang.treetop +0 -197
- data/lib/vm/perror.rb +0 -8
- data/lib/vm/proc.rb +0 -67
- data/lib/vm/std/pdecimal.rb +0 -42
- data/lib/vm/std/pinteger.rb +0 -42
- data/lib/vm/std/pio.rb +0 -17
- data/lib/vm/std/pstring.rb +0 -160
- data/lib/vm/vm.rb +0 -233
- data/test/test_parser_build.txt +0 -72
- data/test/test_vm_programs.txt +0 -64
- data/test/test_vm_results.txt +0 -64
@@ -0,0 +1,130 @@
|
|
1
|
+
module PLang
|
2
|
+
module VM
|
3
|
+
module PFunctions
|
4
|
+
def add_to_interpreter_decimal_functions
|
5
|
+
|
6
|
+
object_message "{decimal: x}", :add do |object|
|
7
|
+
plambda "y" do |value|
|
8
|
+
case value[0].id
|
9
|
+
when :integer, :decimal
|
10
|
+
PObject.new(:decimal, [object.params[0] + value[0].params[0]])
|
11
|
+
else
|
12
|
+
raise "TODO: decimal"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
object_message "{decimal: x}", :sub do |object|
|
18
|
+
plambda "y" do |value|
|
19
|
+
case value[0].id
|
20
|
+
when :integer, :decimal
|
21
|
+
PObject.new(:decimal, [object.params[0] - value[0].params[0]])
|
22
|
+
else
|
23
|
+
raise "TODO: decimal"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
object_message "{decimal: x}", :mul do |object|
|
29
|
+
plambda "y" do |value|
|
30
|
+
case value[0].id
|
31
|
+
when :integer, :decimal
|
32
|
+
PObject.new(:decimal, [object.params[0] * value[0].params[0]])
|
33
|
+
else
|
34
|
+
raise "TODO: decimal"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
object_message "{decimal: x}", :div do |object|
|
40
|
+
plambda "y" do |value|
|
41
|
+
case value[0].id
|
42
|
+
when :integer, :decimal
|
43
|
+
PObject.new(:decimal, [object.params[0] / value[0].params[0]])
|
44
|
+
else
|
45
|
+
raise "TODO: decimal"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
object_message "{decimal: x}", :mod do |object|
|
51
|
+
plambda "y" do |value|
|
52
|
+
case value[0].id
|
53
|
+
when :integer, :decimal
|
54
|
+
PObject.new(:decimal, [object.params[0] % value[0].params[0]])
|
55
|
+
else
|
56
|
+
raise "TODO: decimal"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
object_message "{decimal: x}", :major do |object|
|
62
|
+
plambda "y" do |value|
|
63
|
+
case value[0].id
|
64
|
+
when :integer, :decimal
|
65
|
+
PObject.new(:boolean, [(object.params[0] > value[0].params[0]).to_s.to_sym])
|
66
|
+
else
|
67
|
+
raise "TODO: decimal"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
object_message "{decimal: x}", :major_equal do |object|
|
73
|
+
plambda "y" do |value|
|
74
|
+
case value[0].id
|
75
|
+
when :integer, :decimal
|
76
|
+
PObject.new(:boolean, [(object.params[0] >= value[0].params[0]).to_s.to_sym])
|
77
|
+
else
|
78
|
+
raise "TODO: decimal"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
object_message "{decimal: x}", :minor do |object|
|
84
|
+
plambda "y" do |value|
|
85
|
+
case value[0].id
|
86
|
+
when :integer, :decimal
|
87
|
+
PObject.new(:boolean, [(object.params[0] < value[0].params[0]).to_s.to_sym])
|
88
|
+
else
|
89
|
+
raise "TODO: decimal"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
object_message "{decimal: x}", :minor_equal do |object|
|
95
|
+
plambda "y" do |value|
|
96
|
+
case value[0].id
|
97
|
+
when :integer, :decimal
|
98
|
+
PObject.new(:boolean, [(object.params[0] <= value[0].params[0]).to_s.to_sym])
|
99
|
+
else
|
100
|
+
raise "TODO: decimal"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
object_message "{decimal: x}", :equal do |object|
|
106
|
+
plambda "y" do |value|
|
107
|
+
case value[0].id
|
108
|
+
when :integer, :decimal
|
109
|
+
PObject.new(:boolean, [(object.params[0] == value[0].params[0]).to_s.to_sym])
|
110
|
+
else
|
111
|
+
raise "TODO: decimal"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
object_message "{decimal: x}", :diff do |object|
|
117
|
+
plambda "y" do |value|
|
118
|
+
case value[0].id
|
119
|
+
when :integer, :decimal
|
120
|
+
PObject.new(:boolean, [(object.params[0] != value[0].params[0]).to_s.to_sym])
|
121
|
+
else
|
122
|
+
raise "TODO: decimal"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module PLang
|
2
|
+
module VM
|
3
|
+
module PFunctions
|
4
|
+
def add_to_interpreter_integer_functions
|
5
|
+
|
6
|
+
object_message "{integer: x}", :add do |object|
|
7
|
+
plambda "y" do |value|
|
8
|
+
if value[0].id == :integer
|
9
|
+
PObject.new(:integer, [object.params[0] + value[0].params[0]])
|
10
|
+
elsif value[0].id == :decimal
|
11
|
+
PObject.new(:decimal, [object.params[0] + value[0].params[0]])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
object_message "{integer: x}", :sub do |object|
|
17
|
+
plambda "y" do |value|
|
18
|
+
if value[0].id == :integer
|
19
|
+
PObject.new(:integer, [object.params[0] - value[0].params[0]])
|
20
|
+
elsif value[0].id == :decimal
|
21
|
+
PObject.new(:decimal, [object.params[0] - value[0].params[0]])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
object_message "{integer: x}", :mul do |object|
|
27
|
+
plambda "y" do |value|
|
28
|
+
if value[0].id == :integer
|
29
|
+
PObject.new(:integer, [object.params[0] * value[0].params[0]])
|
30
|
+
elsif value[0].id == :decimal
|
31
|
+
PObject.new(:decimal, [object.params[0] * value[0].params[0]])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
object_message "{integer: x}", :div do |object|
|
37
|
+
plambda "y" do |value|
|
38
|
+
if value[0].id == :integer
|
39
|
+
PObject.new(:integer, [object.params[0] / value[0].params[0]])
|
40
|
+
elsif value[0].id == :decimal
|
41
|
+
PObject.new(:decimal, [object.params[0] / value[0].params[0]])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
object_message "{integer: x}", :mod do |object|
|
47
|
+
plambda "y" do |value|
|
48
|
+
if value[0].id == :integer
|
49
|
+
PObject.new(:integer, [object.params[0] % value[0].params[0]])
|
50
|
+
elsif value[0].id == :decimal
|
51
|
+
PObject.new(:decimal, [object.params[0] % value[0].params[0]])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
object_message "{integer: x}", :major do |object|
|
57
|
+
plambda "y" do |value|
|
58
|
+
case value[0].id
|
59
|
+
when :integer, :decimal
|
60
|
+
PObject.new(:boolean, [(object.params[0] > value[0].params[0]).to_s.to_sym])
|
61
|
+
else
|
62
|
+
raise "TODO: integer"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
object_message "{integer: x}", :major_equal do |object|
|
68
|
+
plambda "y" do |value|
|
69
|
+
case value[0].id
|
70
|
+
when :integer, :decimal
|
71
|
+
PObject.new(:boolean, [(object.params[0] >= value[0].params[0]).to_s.to_sym])
|
72
|
+
else
|
73
|
+
raise "TODO: integer"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
object_message "{integer: x}", :minor do |object|
|
79
|
+
plambda "y" do |value|
|
80
|
+
case value[0].id
|
81
|
+
when :integer, :decimal
|
82
|
+
PObject.new(:boolean, [(object.params[0] < value[0].params[0]).to_s.to_sym])
|
83
|
+
else
|
84
|
+
raise "TODO: integer"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
object_message "{integer: x}", :minor_equal do |object|
|
90
|
+
plambda "y" do |value|
|
91
|
+
case value[0].id
|
92
|
+
when :integer, :decimal
|
93
|
+
PObject.new(:boolean, [(object.params[0] <= value[0].params[0]).to_s.to_sym])
|
94
|
+
else
|
95
|
+
raise "TODO: integer"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
object_message "{integer: x}", :equal do |object|
|
101
|
+
plambda "y" do |value|
|
102
|
+
case value[0].id
|
103
|
+
when :integer, :decimal
|
104
|
+
PObject.new(:boolean, [(object.params[0] == value[0].params[0]).to_s.to_sym])
|
105
|
+
else
|
106
|
+
raise "TODO: integer"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
object_message "{integer: x}", :diff do |object|
|
112
|
+
plambda "y" do |value|
|
113
|
+
case value[0].id
|
114
|
+
when :integer, :decimal
|
115
|
+
PObject.new(:boolean, [(object.params[0] != value[0].params[0]).to_s.to_sym])
|
116
|
+
else
|
117
|
+
raise "TODO: integer"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
data/lib/vm/core/pio.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module PLang
|
2
|
+
module VM
|
3
|
+
module PFunctions
|
4
|
+
def add_to_interpreter_io_functions
|
5
|
+
|
6
|
+
var :print, (plambda "x" do |params|
|
7
|
+
puts params[0].to_s
|
8
|
+
end)
|
9
|
+
|
10
|
+
var :read, (plambda do
|
11
|
+
PObject.new(:string, [STDIN.gets])
|
12
|
+
end)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module PLang
|
2
|
+
module VM
|
3
|
+
module PFunctions
|
4
|
+
def add_to_interpreter_list_functions
|
5
|
+
|
6
|
+
object_message "{list: x, xs}", :head do |object|
|
7
|
+
plambda do |value|
|
8
|
+
object.params[0]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
object_message "{list: x, xs}", :tail do |object|
|
13
|
+
plambda do |value|
|
14
|
+
object.params[1]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
object_message "{list: x, xs}", :concat do |object|
|
19
|
+
plambda "x" do |value|
|
20
|
+
PObject.new(:list, [value[0], object])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
object_message "{empty}", :concat do |object|
|
25
|
+
plambda "x" do |value|
|
26
|
+
PObject.new(:list, [value[0], object])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module PLang
|
2
|
+
module VM
|
3
|
+
module PFunctions
|
4
|
+
def add_to_interpreter_string_functions
|
5
|
+
|
6
|
+
object_message "{string: x}", :at do |object|
|
7
|
+
plambda "{integer: y}" do |value|
|
8
|
+
PObject.new(:char, [object.params[0][value[0].params[0]]])
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
object_message "{string: x}", :concat do |object|
|
13
|
+
plambda "{string: y}" do |value|
|
14
|
+
PObject.new(:string, [object.params[0] + value[0].params[0]])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
object_message "x", :to_string do |object|
|
19
|
+
plambda do |value|
|
20
|
+
PObject.new(:string, [object.to_s])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
object_message "{string: x}", :to_integer do |object|
|
25
|
+
plambda do |value|
|
26
|
+
PObject.new(:integer, [object.params[0].to_i])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
object_message "{string: x}", :to_decimal do |object|
|
31
|
+
plambda do |value|
|
32
|
+
PObject.new(:decimal, [object.params[0].to_f])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/vm/environment.rb
CHANGED
@@ -1,53 +1,78 @@
|
|
1
1
|
module PLang
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
def add_var(id, value)
|
12
|
-
unless @vars[id]
|
13
|
-
@vars[id] = value
|
14
|
-
else
|
15
|
-
PError.raise_error(:BindVariableError, "variable '#{id}'")
|
2
|
+
module VM
|
3
|
+
class Environment
|
4
|
+
attr_accessor :parent
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@vars = Hash.new
|
8
|
+
@objects = Hash.new
|
16
9
|
end
|
17
|
-
end
|
18
10
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
else
|
26
|
-
PError.raise_error(:NameError, "undefined variable '#{id}'")
|
11
|
+
def set_var(id, value)
|
12
|
+
unless @vars[id]
|
13
|
+
@vars[id] = value
|
14
|
+
else
|
15
|
+
raise "LetError: TODO"
|
16
|
+
end
|
27
17
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
18
|
+
|
19
|
+
def get_var(id)
|
20
|
+
v = @vars[id]
|
21
|
+
if v
|
22
|
+
return v
|
23
|
+
elsif @parent
|
24
|
+
return @parent.get_var(id)
|
25
|
+
else
|
26
|
+
raise "NameError: undefined variable '#{id}'"
|
27
|
+
end
|
33
28
|
end
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
29
|
+
|
30
|
+
#TODO: new operator to add lambdas
|
31
|
+
def add_lambda(id, lamb)
|
32
|
+
v = get_var(id)
|
33
|
+
if v
|
34
|
+
if v.id == :lambda and lamb.id == :lambda
|
35
|
+
v.params |= lamb.params
|
36
|
+
else
|
37
|
+
raise "TODO: Environment#add_lambda#2"
|
43
38
|
end
|
39
|
+
else
|
40
|
+
raise "TODO: Environment#add_lambda#1"
|
44
41
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
42
|
+
end
|
43
|
+
|
44
|
+
def set_object_var(form, object)
|
45
|
+
if form.type == :object
|
46
|
+
if form.id.value == object.id
|
47
|
+
form.params.each_with_index do |param, i|
|
48
|
+
case param.type
|
49
|
+
when :object
|
50
|
+
set_object_var(param, object.params[i])
|
51
|
+
when :id
|
52
|
+
unless param.value == :_
|
53
|
+
if object.id == :integer
|
54
|
+
set_var(param.value, PObject.new(:integer, [object.params[i]]))
|
55
|
+
elsif object.id == :decimal
|
56
|
+
set_var(param.value, PObject.new(:decimal, [object.params[i]]))
|
57
|
+
elsif object.id == :char
|
58
|
+
set_var(param.value, PObject.new(:char, [object.params[i]]))
|
59
|
+
elsif object.id == :string
|
60
|
+
set_var(param.value, PObject.new(:string, [object.params[i]]))
|
61
|
+
else
|
62
|
+
set_var(param.value, object.params[i])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
else
|
66
|
+
unless param.value == object.params[i].params[0]
|
67
|
+
raise "TODO: Environment#set_object_var#3"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
else
|
72
|
+
raise "TODO: Environment#set_object_var#1"
|
73
|
+
end
|
49
74
|
else
|
50
|
-
|
75
|
+
raise "TODO: Environment#set_object_var#2"
|
51
76
|
end
|
52
77
|
end
|
53
78
|
end
|