p-lang 0.0.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.
@@ -0,0 +1,197 @@
1
+ grammar PLang
2
+
3
+ rule statements
4
+ (spaces? statement spaces?)* <NStatements>
5
+ end
6
+
7
+ rule statement
8
+ unop / binop / let / object_op / expr
9
+ end
10
+
11
+ rule object_op
12
+ object_msg /
13
+ object_get
14
+ end
15
+
16
+ rule object_msg
17
+ expr spaces? '->' spaces? id sspaces? '(' spaces? statement_list:statement_list? spaces? ')' <NObjectMsg>
18
+ end
19
+
20
+ rule object_get
21
+ expr spaces? '->' spaces? id spaces? <NObjectGet>
22
+ end
23
+
24
+ rule let
25
+ var_let /
26
+ obj_let
27
+ end
28
+
29
+ rule var_let
30
+ var spaces? '=' spaces? statement <NVarLet>
31
+ end
32
+
33
+ rule obj_let
34
+ object_form spaces? '->' spaces? var spaces? '=' spaces? statement <NObjectLet>
35
+ end
36
+
37
+ rule var
38
+ id / object
39
+ end
40
+
41
+ rule unop
42
+ 'not' spaces? statement <NUnOp>
43
+ end
44
+
45
+ rule binop
46
+ expr spaces? op spaces? statement <NBinOp>
47
+ end
48
+
49
+ rule op
50
+ '+' / '-' / '*' / '/' / '%' / '>=' / '<=' / '>' / '<' / '==' / 'and' / 'or'
51
+ end
52
+
53
+ rule call
54
+ cid:(id / lambda) sspaces? '(' spaces? cparams:statement_list? spaces? ')' <NCall>
55
+ end
56
+
57
+ rule sspaces
58
+ [\s\t]*
59
+ end
60
+
61
+ rule expr
62
+ number / boolean / call / id / object / char / string / lambda / parem_expr
63
+ end
64
+
65
+ rule parem_expr
66
+ '(' spaces? statement spaces? ')' <NParemExpr>
67
+ end
68
+
69
+ rule statement_list
70
+ cstatement_list / statement
71
+ end
72
+
73
+ rule cstatement_list
74
+ statement spaces? ',' spaces? statement_list <NCStatementList>
75
+ end
76
+
77
+ rule lambda
78
+ clamb / lamb
79
+ end
80
+
81
+ rule clamb
82
+ lamb spaces? ',' spaces? lambda <NCLambda>
83
+ end
84
+
85
+ rule lamb
86
+ '[' spaces? params:lambda_params? spaces? statement spaces? ']' spaces? where:where? <NLambda>
87
+ end
88
+
89
+ rule where
90
+ ':' spaces? '(' spaces? where_params spaces? ')' <NWhere>
91
+ end
92
+
93
+ rule where_params
94
+ cwhere_params / let
95
+ end
96
+
97
+ rule cwhere_params
98
+ let spaces? ',' spaces? where_params <NCWhereParams>
99
+ end
100
+
101
+ rule lambda_params
102
+ lambda_params_list spaces? '|' <NLambdaParams>
103
+ end
104
+
105
+ rule lambda_params_list
106
+ clambda_params_list / form
107
+ end
108
+
109
+ rule clambda_params_list
110
+ form spaces? ',' spaces? lambda_params_list <NCLambdaParamsList>
111
+ end
112
+
113
+ rule form
114
+ number / id / object_form / char / string
115
+ end
116
+
117
+ rule object_form
118
+ '{' spaces? id spaces? obj_form_list:object_form_list? spaces? '}' <NObjectForm>
119
+ end
120
+
121
+ rule object_form_list
122
+ ':' spaces? lambda_params_list <NLambdaParams>
123
+ end
124
+
125
+ rule object
126
+ '{' spaces? id spaces? obj_list:object_list? spaces? '}' <NObject>
127
+ end
128
+
129
+ rule object_list
130
+ ':' spaces? statement_list <NObjectList>
131
+ end
132
+
133
+ rule boolean
134
+ (true / false) <NBoolean>
135
+ end
136
+
137
+ rule true
138
+ "true"
139
+ end
140
+
141
+ rule false
142
+ "false"
143
+ end
144
+
145
+ rule id
146
+ [a-zA-Z_0-9]+ <NId>
147
+ end
148
+
149
+ rule string
150
+ "\"" str:(!"\"" .)* "\"" <NString>
151
+ end
152
+
153
+ rule char
154
+ "'" c:(!"'" .) "'" <NChar>
155
+ end
156
+
157
+ rule number
158
+ decimal / integer
159
+ end
160
+
161
+ rule decimal
162
+ sign? spaces? digits? dot digits <NDecimal>
163
+ end
164
+
165
+ rule integer
166
+ sign? spaces? digits <NInteger>
167
+ end
168
+
169
+ rule digits
170
+ digit+
171
+ end
172
+
173
+ rule digit
174
+ [0-9]
175
+ end
176
+
177
+ rule sign
178
+ "-"
179
+ end
180
+
181
+ rule dot
182
+ "."
183
+ end
184
+
185
+ rule spaces
186
+ space* ("#" (!break .)* break+ space*)*
187
+ end
188
+
189
+ rule space
190
+ [\r\n\t\s]
191
+ end
192
+
193
+ rule break
194
+ [\r\n]
195
+ end
196
+
197
+ end
@@ -0,0 +1,51 @@
1
+ module PLang
2
+ class Environment
3
+ attr_accessor :parent
4
+
5
+ def initialize
6
+ @vars = Hash.new
7
+ @parent = nil
8
+ @object_call = Hash.new
9
+ end
10
+
11
+ def add_var(id, value)
12
+ unless @vars[id]
13
+ @vars[id] = value
14
+ else
15
+ raise "add_var"
16
+ end
17
+ end
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 "get_var"
27
+ end
28
+ end
29
+
30
+ def add_object_call(form, msg, value)
31
+ unless @object_call[msg]
32
+ @object_call[msg] = Hash.new
33
+ end
34
+ @object_call[msg][form] = value
35
+ end
36
+
37
+ def get_object_call(object, msg)
38
+ begin
39
+ lamb = []
40
+ @object_call[msg].each do |obj|
41
+ if obj[0][1] == object.type
42
+ lamb |= obj[1]
43
+ end
44
+ end
45
+ return lamb
46
+ rescue
47
+ raise "get_object_call"
48
+ end
49
+ end
50
+ end
51
+ end
data/lib/vm/pobject.rb ADDED
@@ -0,0 +1,47 @@
1
+ module PLang
2
+ class PObject
3
+ attr_accessor :type
4
+ attr_accessor :params
5
+
6
+ def initialize(type, params)
7
+ @type = type
8
+ @params = params
9
+ end
10
+
11
+ def ==(obj)
12
+ if @type == obj.type
13
+ @params.each_with_index do |param, i|
14
+ unless param == obj.params[i]
15
+ return false
16
+ end
17
+ end
18
+ return true
19
+ else
20
+ return false
21
+ end
22
+ end
23
+
24
+ def form
25
+ case @type
26
+ when :integer, :decimal, :boolean, :char, :string
27
+ [:literal, @type, @params[0]]
28
+ else
29
+ [:object, @type, @params.collect(&:form)]
30
+ end
31
+ end
32
+
33
+ def to_s
34
+ case @type
35
+ when :integer, :decimal, :boolean
36
+ @params[0]
37
+ when :string
38
+ "\"#{@params[0]}\""
39
+ when :char
40
+ "\'#{@params[0]}\'"
41
+ else
42
+ "{#{@type}: #{@params.collect(&:to_s).join(",")}}"
43
+ end
44
+ end
45
+
46
+ end
47
+ end
data/lib/vm/proc.rb ADDED
@@ -0,0 +1,41 @@
1
+ class Proc
2
+ def form=(form)
3
+ @form = form
4
+ end
5
+
6
+ def compare_form(form, obj)
7
+ if(form)
8
+ unless obj[1] == form[1]
9
+ return false
10
+ else
11
+ if form[0] == :literal
12
+ unless form == obj
13
+ return false
14
+ end
15
+ else
16
+ form[2].each_with_index do |p, i|
17
+ unless p[0] == :id
18
+ unless p == obj[2][i]
19
+ if p[0] == :object
20
+ return compare_form(p, obj[2][i])
21
+ else
22
+ return false
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ return true
31
+ end
32
+
33
+ def call?(params)
34
+ params.each_with_index do |param, i|
35
+ unless compare_form(@form[i], param.form)
36
+ return false
37
+ end
38
+ end
39
+ return true
40
+ end
41
+ end
data/lib/vm/std/io.rb ADDED
@@ -0,0 +1,17 @@
1
+ module PLang
2
+ module IO
3
+ def IO.def_pfunctions(env)
4
+ env.add_var(:print, IO.pprint)
5
+ end
6
+
7
+ def IO.pprint
8
+ lamb = Proc.new do |values|
9
+ values.each do |value|
10
+ puts value.to_s
11
+ end
12
+ end
13
+ lamb.form = []
14
+ [lamb]
15
+ end
16
+ end
17
+ end
data/lib/vm/vm.rb ADDED
@@ -0,0 +1,211 @@
1
+ module PLang
2
+ class VM
3
+ def initialize(ast)
4
+ @ast = ast
5
+ end
6
+
7
+ def execute!
8
+ env = PLang::Environment.new
9
+ initialize_global_environment(env)
10
+ @ast.each do |expr|
11
+ @ret = execute(expr, env)
12
+ end
13
+ @ret
14
+ end
15
+
16
+ def execute(expr, env)
17
+ case expr[0]
18
+ when :literal
19
+ execute_literal(expr[1], expr[2], env)
20
+ when :let
21
+ execute_let(expr[1], expr[2], env)
22
+ when :lambda
23
+ execute_lambda(expr[1], expr[2], expr[3], expr[4], env)
24
+ when :call
25
+ execute_call(expr[1], expr[2], env)
26
+ when :id
27
+ execute_id(expr[1], env)
28
+ when :+, :-, :*, :/, :%, :>, :<, :>=, :<=, :==
29
+ execute_binop(expr[0], expr[1], expr[2], env)
30
+ when :and
31
+ execute_and(expr[1], expr[2], env)
32
+ when :or
33
+ execute_or(expr[1], expr[2], env)
34
+ when :if
35
+ execute_if(expr[1], expr[2], expr[3], env)
36
+ when :begin
37
+ execute_begin(expr[1], env)
38
+ when :object
39
+ execute_object(expr[1], expr[2], env)
40
+ when :object_let
41
+ execute_object_let(expr[1], expr[2], expr[3], env)
42
+ when :object_call
43
+ execute_object_call(expr[1], expr[2], env)
44
+ end
45
+ end
46
+
47
+ def execute_literal(type, value, env)
48
+ case type
49
+ when :integer, :decimal, :char, :string
50
+ PObject.new(type, [value])
51
+ when :boolean
52
+ if value == :true
53
+ PObject.new(:boolean, [true])
54
+ elsif value == :false
55
+ PObject.new(:boolean, [false])
56
+ end
57
+ end
58
+ end
59
+
60
+ def execute_let(id, value, env)
61
+ case id[0]
62
+ when :id
63
+ unless id[1] == :_
64
+ env.add_var(id[1], execute(value, env))
65
+ end
66
+ when :object
67
+ add_object_var(id, execute(value, env), env)
68
+ end
69
+ end
70
+
71
+ def add_object_var(obj, value, env)
72
+ if obj[1] == value.type
73
+ obj[2].each_with_index do |param, i|
74
+ case param[0]
75
+ when :id
76
+ unless param[1] == :_
77
+ case value.type
78
+ when :integer, :decimal, :boolean
79
+ env.add_var(param[1], PObject.new(value.type, [value.params[i]]))
80
+ else
81
+ env.add_var(param[1], value.params[i])
82
+ end
83
+ end
84
+ when :object
85
+ add_object_var(param, value.params[i], env)
86
+ else
87
+ unless execute(param, env) == value.params[i]
88
+ raise "add_object_var #1"
89
+ end
90
+ end
91
+ end
92
+ else
93
+ raise "add_object_var #2"
94
+ end
95
+ end
96
+
97
+ def execute_lambda(params, body, where, next_lambda, env)
98
+ lambda = []
99
+ lambda << Proc.new do |values|
100
+ new_env = PLang::Environment.new
101
+ new_env.parent = env
102
+ values.each_with_index do |value, i|
103
+ case params[i][0]
104
+ when :id
105
+ unless params[i][1] == :_
106
+ new_env.add_var(params[i][1], value)
107
+ end
108
+ when :object
109
+ add_object_var(params[i], value, new_env)
110
+ end
111
+ end
112
+ where.each do |w|
113
+ execute(w, new_env)
114
+ end
115
+ execute(body, new_env)
116
+ end
117
+ form = []
118
+ params.each do |param|
119
+ case param[0]
120
+ when :id
121
+ form << nil
122
+ when :object
123
+ form << param
124
+ else
125
+ form << execute(param, env).form
126
+ end
127
+ end
128
+ lambda[0].form = form
129
+ if next_lambda
130
+ lambda |= execute(next_lambda, env)
131
+ end
132
+ lambda
133
+ end
134
+
135
+ def execute_call(id, params, env)
136
+ values = []
137
+ params.each do |param|
138
+ values << execute(param, env)
139
+ end
140
+ execute(id, env).each do |lambda|
141
+ if lambda.call?(values)
142
+ return lambda.call(values)
143
+ end
144
+ end
145
+ raise "execute_call"
146
+ end
147
+
148
+ def execute_id(id, env)
149
+ env.get_var(id)
150
+ end
151
+
152
+ def execute_binop(op, lhs, rhs, env)
153
+ lhs = execute(lhs, env)
154
+ rhs = execute(rhs, env)
155
+ result = lhs.params[0].send(op,rhs.params[0])
156
+ if result.class == Fixnum or result.class == Bignum
157
+ return PObject.new(:integer, [result])
158
+ elsif result.class == Float
159
+ return PObject.new(:decimal, [result])
160
+ elsif result.class == TrueClass or result.class == FalseClass
161
+ return PObject.new(:boolean, [result])
162
+ end
163
+ end
164
+
165
+ def execute_and(lhs, rhs, env)
166
+ lhs = execute(lhs, env)
167
+ rhs = execute(rhs, env)
168
+ PObject.new(:boolean, [(lhs.params[0] and rhs.params[0])])
169
+ end
170
+
171
+ def execute_or(lhs, rhs, env)
172
+ lhs = execute(lhs, env)
173
+ rhs = execute(rhs, env)
174
+ PObject.new(:boolean, [(lhs.params[0] or rhs.params[0])])
175
+ end
176
+
177
+ def execute_if(cond, t, f, env)
178
+ cond = execute(cond, env)
179
+ if cond.params[0]
180
+ execute(t, env)
181
+ else
182
+ execute(f, env)
183
+ end
184
+ end
185
+
186
+ def execute_begin(exprs, env)
187
+ ret = nil
188
+ exprs.each do |expr|
189
+ ret = execute(expr, env)
190
+ end
191
+ ret
192
+ end
193
+
194
+ def execute_object(type, params, env)
195
+ values = []
196
+ params.each do |param|
197
+ values << execute(param, env)
198
+ end
199
+ PObject.new(type, values)
200
+ end
201
+
202
+ def execute_object_let(obj, msg, value, env)
203
+ value[1] << obj
204
+ env.add_object_call(obj, msg[1], execute(value, env))
205
+ end
206
+
207
+ def execute_object_call(object, id, env)
208
+ env.get_object_call(execute(object, env), id[1])
209
+ end
210
+ end
211
+ end