p-lang 0.1.1 → 0.2.0
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.
- 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
|