p-lang 0.0.4 → 0.1.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 +26 -0
- data/VERSION.yml +2 -2
- data/bin/p-lang +1 -0
- data/bin/teste.p +0 -5
- data/lib/p-lang.rb +8 -2
- data/lib/vm/perror.rb +1 -1
- data/lib/vm/proc.rb +24 -10
- data/lib/vm/std/pdecimal.rb +42 -0
- data/lib/vm/std/pinteger.rb +42 -0
- data/lib/vm/std/{io.rb → pio.rb} +4 -4
- data/lib/vm/std/pstring.rb +160 -0
- data/lib/vm/vm.rb +12 -4
- data/test/test_vm_programs.txt +25 -0
- data/test/test_vm_results.txt +25 -0
- metadata +8 -5
data/README.rdoc
CHANGED
@@ -8,6 +8,32 @@ P is a small ('pequena' in portuguese) functional programming language.
|
|
8
8
|
|
9
9
|
fib(10)
|
10
10
|
|
11
|
+
= Features
|
12
|
+
|
13
|
+
Functions:
|
14
|
+
|
15
|
+
fib = [1| 1],
|
16
|
+
[2| 1],
|
17
|
+
[n| fib(n-1) + fib(n-2)]
|
18
|
+
|
19
|
+
fib(10)
|
20
|
+
|
21
|
+
Objects:
|
22
|
+
|
23
|
+
{rectangle: 10, 30}
|
24
|
+
|
25
|
+
Pattern:
|
26
|
+
|
27
|
+
{rectangle: x, y} = {rectangle: 10, 30}
|
28
|
+
# => x = 10
|
29
|
+
# => y = 30
|
30
|
+
|
31
|
+
Messages:
|
32
|
+
|
33
|
+
{integer: x} -> plus2 = [x+2]
|
34
|
+
|
35
|
+
3->plus2() # => 5
|
36
|
+
|
11
37
|
== Requirements
|
12
38
|
|
13
39
|
* Ruby
|
data/VERSION.yml
CHANGED
data/bin/p-lang
CHANGED
data/lib/p-lang.rb
CHANGED
@@ -14,12 +14,18 @@ require File.join(ROOT_PATH, '/vm/proc')
|
|
14
14
|
require File.join(ROOT_PATH, '/vm/pobject')
|
15
15
|
require File.join(ROOT_PATH, '/vm/perror')
|
16
16
|
|
17
|
-
require File.join(ROOT_PATH, '/vm/std/
|
17
|
+
require File.join(ROOT_PATH, '/vm/std/pio')
|
18
|
+
require File.join(ROOT_PATH, '/vm/std/pstring')
|
19
|
+
require File.join(ROOT_PATH, '/vm/std/pinteger')
|
20
|
+
require File.join(ROOT_PATH, '/vm/std/pdecimal')
|
18
21
|
|
19
22
|
module PLang
|
20
23
|
class VM
|
21
24
|
def initialize_global_environment(env)
|
22
|
-
|
25
|
+
PIO.def_pfunctions(env)
|
26
|
+
PString.def_pfunctions(env)
|
27
|
+
PInteger.def_pfunctions(env)
|
28
|
+
PDecimal.def_pfunctions(env)
|
23
29
|
end
|
24
30
|
end
|
25
31
|
end
|
data/lib/vm/perror.rb
CHANGED
data/lib/vm/proc.rb
CHANGED
@@ -11,20 +11,30 @@ class Proc
|
|
11
11
|
return false
|
12
12
|
end
|
13
13
|
else
|
14
|
-
if
|
15
|
-
form[2].
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
14
|
+
if obj[0] == :literal
|
15
|
+
unless form[2].length == 1
|
16
|
+
return false
|
17
|
+
else
|
18
|
+
unless form[2][0][0] == :id
|
19
|
+
return false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
else
|
23
|
+
if form[2].length == obj[2].length
|
24
|
+
form[2].each_with_index do |p, i|
|
25
|
+
unless p[0] == :id
|
26
|
+
unless p == obj[2][i]
|
27
|
+
if p[0] == :object
|
28
|
+
return compare_form(p, obj[2][i])
|
29
|
+
else
|
30
|
+
return false
|
31
|
+
end
|
22
32
|
end
|
23
33
|
end
|
24
34
|
end
|
35
|
+
else
|
36
|
+
return false
|
25
37
|
end
|
26
|
-
else
|
27
|
-
return false
|
28
38
|
end
|
29
39
|
end
|
30
40
|
end
|
@@ -50,4 +60,8 @@ class Proc
|
|
50
60
|
return false
|
51
61
|
end
|
52
62
|
end
|
63
|
+
|
64
|
+
def to_s
|
65
|
+
"#lambda:#{self.object_id}"
|
66
|
+
end
|
53
67
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module PLang
|
2
|
+
module PDecimal
|
3
|
+
def PDecimal.def_pfunctions(env)
|
4
|
+
env.add_object_call([:object, :decimal, [[:id, :x]]], :abs, PDecimal.abs)
|
5
|
+
env.add_object_call([:object, :decimal, [[:id, :x]]], :ceil, PDecimal.ceil)
|
6
|
+
env.add_object_call([:object, :decimal, [[:id, :x]]], :floor, PDecimal.floor)
|
7
|
+
env.add_object_call([:object, :decimal, [[:id, :x]]], :to_string, PDecimal.to_string)
|
8
|
+
end
|
9
|
+
|
10
|
+
def PDecimal.abs
|
11
|
+
lamb = Proc.new do |values|
|
12
|
+
PObject.new(:decimal, [values[0].params[0].abs])
|
13
|
+
end
|
14
|
+
lamb.form = [[:object, :decimal, [[:id, :x]]]]
|
15
|
+
[lamb]
|
16
|
+
end
|
17
|
+
|
18
|
+
def PDecimal.ceil
|
19
|
+
lamb = Proc.new do |values|
|
20
|
+
PObject.new(:decimal, [values[0].params[0].ceil])
|
21
|
+
end
|
22
|
+
lamb.form = [[:object, :decimal, [[:id, :x]]]]
|
23
|
+
[lamb]
|
24
|
+
end
|
25
|
+
|
26
|
+
def PDecimal.floor
|
27
|
+
lamb = Proc.new do |values|
|
28
|
+
PObject.new(:decimal, [values[0].params[0].floor])
|
29
|
+
end
|
30
|
+
lamb.form = [[:object, :decimal, [[:id, :x]]]]
|
31
|
+
[lamb]
|
32
|
+
end
|
33
|
+
|
34
|
+
def PDecimal.to_string
|
35
|
+
lamb = Proc.new do |values|
|
36
|
+
PObject.new(:string, [values[0].params[0].to_s])
|
37
|
+
end
|
38
|
+
lamb.form = [[:object, :decimal, [[:id, :x]]]]
|
39
|
+
[lamb]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module PLang
|
2
|
+
module PInteger
|
3
|
+
def PInteger.def_pfunctions(env)
|
4
|
+
env.add_object_call([:object, :integer, [[:id, :x]]], :abs, PInteger.abs)
|
5
|
+
env.add_object_call([:object, :integer, [[:id, :x]]], :to_decimal, PInteger.to_decimal)
|
6
|
+
env.add_object_call([:object, :integer, [[:id, :x]]], :to_string, PInteger.to_string)
|
7
|
+
env.add_object_call([:object, :integer, [[:id, :x]]], :next, PInteger.next)
|
8
|
+
end
|
9
|
+
|
10
|
+
def PInteger.abs
|
11
|
+
lamb = Proc.new do |values|
|
12
|
+
PObject.new(:integer, [values[0].params[0].abs])
|
13
|
+
end
|
14
|
+
lamb.form = [[:object, :integer, [[:id, :x]]]]
|
15
|
+
[lamb]
|
16
|
+
end
|
17
|
+
|
18
|
+
def PInteger.next
|
19
|
+
lamb = Proc.new do |values|
|
20
|
+
PObject.new(:integer, [values[0].params[0].next])
|
21
|
+
end
|
22
|
+
lamb.form = [[:object, :integer, [[:id, :x]]]]
|
23
|
+
[lamb]
|
24
|
+
end
|
25
|
+
|
26
|
+
def PInteger.to_decimal
|
27
|
+
lamb = Proc.new do |values|
|
28
|
+
PObject.new(:decimal, [values[0].params[0].to_f])
|
29
|
+
end
|
30
|
+
lamb.form = [[:object, :integer, [[:id, :x]]]]
|
31
|
+
[lamb]
|
32
|
+
end
|
33
|
+
|
34
|
+
def PInteger.to_string
|
35
|
+
lamb = Proc.new do |values|
|
36
|
+
PObject.new(:string, [values[0].params[0].to_s])
|
37
|
+
end
|
38
|
+
lamb.form = [[:object, :integer, [[:id, :x]]]]
|
39
|
+
[lamb]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/vm/std/{io.rb → pio.rb}
RENAMED
@@ -1,10 +1,10 @@
|
|
1
1
|
module PLang
|
2
|
-
module
|
3
|
-
def
|
4
|
-
env.add_var(:print,
|
2
|
+
module PIO
|
3
|
+
def PIO.def_pfunctions(env)
|
4
|
+
env.add_var(:print, PIO.pprint)
|
5
5
|
end
|
6
6
|
|
7
|
-
def
|
7
|
+
def PIO.pprint
|
8
8
|
lamb = Proc.new do |values|
|
9
9
|
values.each do |value|
|
10
10
|
puts value.to_s
|
@@ -0,0 +1,160 @@
|
|
1
|
+
module PLang
|
2
|
+
module PString
|
3
|
+
def PString.def_pfunctions(env)
|
4
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :append, PString.append)
|
5
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :equal, PString.equal)
|
6
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :at, PString.at)
|
7
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :capitalize, PString.capitalize)
|
8
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :center, PString.center)
|
9
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :downcase, PString.downcase)
|
10
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :is_empty, PString.is_empty)
|
11
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :hex, PString.hex)
|
12
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :index, PString.index)
|
13
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :insert, PString.insert)
|
14
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :length, PString.length)
|
15
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :oct, PString.oct)
|
16
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :reverse, PString.reverse)
|
17
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :to_integer, PString.to_integer)
|
18
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :to_decimal, PString.to_decimal)
|
19
|
+
env.add_object_call([:object, :string, [[:id, :x]]], :upcase, PString.upcase)
|
20
|
+
end
|
21
|
+
|
22
|
+
def PString.append
|
23
|
+
lamb = Proc.new do |values|
|
24
|
+
PObject.new(:string, [values[0].params[0] + values[1].params[0]])
|
25
|
+
end
|
26
|
+
lamb.form = [[:object, :string, [[:id, :x]]], [:object, :string, [[:id, :x]]]]
|
27
|
+
[lamb]
|
28
|
+
end
|
29
|
+
|
30
|
+
def PString.equal
|
31
|
+
lamb = Proc.new do |values|
|
32
|
+
if values[0].params[0] == values[1].params[0]
|
33
|
+
PObject.new(:boolean, [true])
|
34
|
+
else
|
35
|
+
PObject.new(:boolean, [false])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
lamb.form = [[:object, :string, [[:id, :x]]], [:object, :string, [[:id, :x]]]]
|
39
|
+
[lamb]
|
40
|
+
end
|
41
|
+
|
42
|
+
def PString.at
|
43
|
+
lamb = Proc.new do |values|
|
44
|
+
PObject.new(:char, [values[0].params[0][values[1].params[0],1]])
|
45
|
+
end
|
46
|
+
lamb.form = [[:object, :string, [[:id, :x]]], [:object, :integer, [[:id, :x]]]]
|
47
|
+
[lamb]
|
48
|
+
end
|
49
|
+
|
50
|
+
def PString.capitalize
|
51
|
+
lamb = Proc.new do |values|
|
52
|
+
PObject.new(:string, [values[0].params[0].capitalize])
|
53
|
+
end
|
54
|
+
lamb.form = [[:object, :string, [[:id, :x]]]]
|
55
|
+
[lamb]
|
56
|
+
end
|
57
|
+
|
58
|
+
def PString.center
|
59
|
+
lamb = Proc.new do |values|
|
60
|
+
PObject.new(:string, [values[0].params[0].center(values[1].params[0])])
|
61
|
+
end
|
62
|
+
lamb.form = [[:object, :string, [[:id, :x]]], [:object, :integer, [[:id, :x]]]]
|
63
|
+
[lamb]
|
64
|
+
end
|
65
|
+
|
66
|
+
def PString.downcase
|
67
|
+
lamb = Proc.new do |values|
|
68
|
+
PObject.new(:string, [values[0].params[0].downcase])
|
69
|
+
end
|
70
|
+
lamb.form = [[:object, :string, [[:id, :x]]]]
|
71
|
+
[lamb]
|
72
|
+
end
|
73
|
+
|
74
|
+
def PString.is_empty
|
75
|
+
lamb = Proc.new do |values|
|
76
|
+
PObject.new(:boolean, [values[0].params[0].empty?])
|
77
|
+
end
|
78
|
+
lamb.form = [[:object, :string, [[:id, :x]]]]
|
79
|
+
[lamb]
|
80
|
+
end
|
81
|
+
|
82
|
+
def PString.hex
|
83
|
+
lamb = Proc.new do |values|
|
84
|
+
PObject.new(:integer, [values[0].params[0].hex])
|
85
|
+
end
|
86
|
+
lamb.form = [[:object, :string, [[:id, :x]]]]
|
87
|
+
[lamb]
|
88
|
+
end
|
89
|
+
|
90
|
+
def PString.index
|
91
|
+
lamb = Proc.new do |values|
|
92
|
+
i = values[0].params[0].index(values[1].params[0])
|
93
|
+
if i
|
94
|
+
PObject.new(:integer, [i])
|
95
|
+
else
|
96
|
+
PObject.new(:nil, [])
|
97
|
+
end
|
98
|
+
end
|
99
|
+
lamb.form = [[:object, :string, [[:id, :x]]], [:object, :string, [[:id, :x]]]]
|
100
|
+
[lamb]
|
101
|
+
end
|
102
|
+
|
103
|
+
def PString.insert
|
104
|
+
lamb = Proc.new do |values|
|
105
|
+
PObject.new(:string, [values[0].params[0].insert(values[1].params[0], values[2].params[0])])
|
106
|
+
end
|
107
|
+
lamb.form = [[:object, :string, [[:id, :x]]], [:object, :integer, [[:id, :x]]], [:object, :string, [[:id, :x]]]]
|
108
|
+
[lamb]
|
109
|
+
end
|
110
|
+
|
111
|
+
def PString.length
|
112
|
+
lamb = Proc.new do |values|
|
113
|
+
PObject.new(:integer, [values[0].params[0].length])
|
114
|
+
end
|
115
|
+
lamb.form = [[:object, :string, [[:id, :x]]]]
|
116
|
+
[lamb]
|
117
|
+
end
|
118
|
+
|
119
|
+
def PString.oct
|
120
|
+
lamb = Proc.new do |values|
|
121
|
+
PObject.new(:integer, [values[0].params[0].oct])
|
122
|
+
end
|
123
|
+
lamb.form = [[:object, :string, [[:id, :x]]]]
|
124
|
+
[lamb]
|
125
|
+
end
|
126
|
+
|
127
|
+
def PString.reverse
|
128
|
+
lamb = Proc.new do |values|
|
129
|
+
PObject.new(:string, [values[0].params[0].reverse])
|
130
|
+
end
|
131
|
+
lamb.form = [[:object, :string, [[:id, :x]]]]
|
132
|
+
[lamb]
|
133
|
+
end
|
134
|
+
|
135
|
+
def PString.to_integer
|
136
|
+
lamb = Proc.new do |values|
|
137
|
+
PObject.new(:integer, [values[0].params[0].to_i])
|
138
|
+
end
|
139
|
+
lamb.form = [[:object, :string, [[:id, :x]]]]
|
140
|
+
[lamb]
|
141
|
+
end
|
142
|
+
|
143
|
+
def PString.to_decimal
|
144
|
+
lamb = Proc.new do |values|
|
145
|
+
PObject.new(:decimal, [values[0].params[0].to_f])
|
146
|
+
end
|
147
|
+
lamb.form = [[:object, :string, [[:id, :x]]]]
|
148
|
+
[lamb]
|
149
|
+
end
|
150
|
+
|
151
|
+
def PString.upcase
|
152
|
+
lamb = Proc.new do |values|
|
153
|
+
PObject.new(:string, [values[0].params[0].upcase])
|
154
|
+
end
|
155
|
+
lamb.form = [[:object, :string, [[:id, :x]]]]
|
156
|
+
[lamb]
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
end
|
data/lib/vm/vm.rb
CHANGED
@@ -144,11 +144,13 @@ module PLang
|
|
144
144
|
end
|
145
145
|
end
|
146
146
|
# CallFunctionError
|
147
|
+
ok = false
|
147
148
|
str_value = "("
|
148
149
|
values.each do |v|
|
149
150
|
str_value += "#{v.to_s}" + ","
|
151
|
+
ok = true
|
150
152
|
end
|
151
|
-
if
|
153
|
+
if ok
|
152
154
|
str_value[-1] = ")"
|
153
155
|
else
|
154
156
|
str_value += ")"
|
@@ -166,6 +168,8 @@ module PLang
|
|
166
168
|
def execute_binop(op, lhs, rhs, env)
|
167
169
|
lhs = execute(lhs, env)
|
168
170
|
rhs = execute(rhs, env)
|
171
|
+
#p lhs
|
172
|
+
#p rhs
|
169
173
|
result = lhs.params[0].send(op,rhs.params[0])
|
170
174
|
if result.class == Fixnum or result.class == Bignum
|
171
175
|
return PObject.new(:integer, [result])
|
@@ -207,10 +211,14 @@ module PLang
|
|
207
211
|
|
208
212
|
def execute_object(type, params, env)
|
209
213
|
values = []
|
210
|
-
params.
|
211
|
-
|
214
|
+
if type == :integer and params.length == 1
|
215
|
+
return PObject.new(type, [params[0][2]])
|
216
|
+
else
|
217
|
+
params.each do |param|
|
218
|
+
values << execute(param, env)
|
219
|
+
end
|
220
|
+
return PObject.new(type, values)
|
212
221
|
end
|
213
|
-
PObject.new(type, values)
|
214
222
|
end
|
215
223
|
|
216
224
|
def execute_object_let(obj, msg, value, env)
|
data/test/test_vm_programs.txt
CHANGED
@@ -37,3 +37,28 @@ f = [_,x,_| x*2] f(1,2,3)
|
|
37
37
|
f = [{obj: {xxx: _}, x}, y| x+y] f({obj: {xxx: 1}, 2}, 3)
|
38
38
|
list_sum = [{list: head, tail}| head + list_sum(tail)], [{list}| 0] list_sum({list: 1, {list: 2, {list}}})
|
39
39
|
f = [x| x(10)] g = [x| x+1] f(g)
|
40
|
+
"aaaaa"->append("bbbbb")
|
41
|
+
"aaaaa"->equal("bbbbb")
|
42
|
+
"aaaaa"->equal("aaaaa")
|
43
|
+
"abcde"->at(2)
|
44
|
+
"abcde"->capitalize()
|
45
|
+
"abcde"->center(10)
|
46
|
+
"aBcDe"->downcase()
|
47
|
+
"aBcDe"->is_empty()
|
48
|
+
"0xB"->hex()
|
49
|
+
"abcde"->index("c")
|
50
|
+
"abcde"->insert(3, "X")
|
51
|
+
"abcde"->length()
|
52
|
+
"10"->oct()
|
53
|
+
"abcde"->reverse()
|
54
|
+
"10"->to_integer()
|
55
|
+
"10.11"->to_decimal()
|
56
|
+
"aBcDe"->upcase()
|
57
|
+
(-1)->abs()
|
58
|
+
(-1)->next()
|
59
|
+
(-1)->to_decimal()
|
60
|
+
(-1)->to_string()
|
61
|
+
(-1.1)->abs()
|
62
|
+
(-1.1)->ceil()
|
63
|
+
(-1.1)->floor()
|
64
|
+
(-1.1)->to_string()
|
data/test/test_vm_results.txt
CHANGED
@@ -37,3 +37,28 @@ true
|
|
37
37
|
5
|
38
38
|
3
|
39
39
|
11
|
40
|
+
"aaaaabbbbb"
|
41
|
+
false
|
42
|
+
true
|
43
|
+
"c"
|
44
|
+
"Abcde"
|
45
|
+
" abcde "
|
46
|
+
"abcde"
|
47
|
+
false
|
48
|
+
11
|
49
|
+
2
|
50
|
+
"abcXde"
|
51
|
+
5
|
52
|
+
8
|
53
|
+
"edcba"
|
54
|
+
10
|
55
|
+
10.11
|
56
|
+
"ABCDE"
|
57
|
+
1
|
58
|
+
0
|
59
|
+
-1.0
|
60
|
+
"-1"
|
61
|
+
1.1
|
62
|
+
-1
|
63
|
+
-2
|
64
|
+
"-1.1"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: p-lang
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.4
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Igor Bonadio
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-07-
|
18
|
+
date: 2010-07-12 00:00:00 -03:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -72,7 +72,10 @@ files:
|
|
72
72
|
- lib/vm/perror.rb
|
73
73
|
- lib/vm/pobject.rb
|
74
74
|
- lib/vm/proc.rb
|
75
|
-
- lib/vm/std/
|
75
|
+
- lib/vm/std/pdecimal.rb
|
76
|
+
- lib/vm/std/pinteger.rb
|
77
|
+
- lib/vm/std/pio.rb
|
78
|
+
- lib/vm/std/pstring.rb
|
76
79
|
- lib/vm/vm.rb
|
77
80
|
- test/helper.rb
|
78
81
|
- test/test_parser.rb
|