p-lang 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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