This repository was archived by the owner on Jul 27, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcompile.rb
More file actions
75 lines (65 loc) · 1.57 KB
/
compile.rb
File metadata and controls
75 lines (65 loc) · 1.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# Lexer (Tokenizer) (turns strings into tokens)
class Tokenizer
TOKEN_TYPES = [
[:def, /\bdef\b/],
[:end, /\bend\b/],
[:identifier, /\b[a-zA-Z]+\b/],
[:integer, /\b[0-9]+\b/],
[:open_paren, /\(/],
[:close_paren, /\)/],
[:comma, /\,/]
]
def initialize(code)
@code = code
end
def tokenize
tokens = []
tokens << grab_one_token until @code.empty?
tokens
end
def grab_one_token
@code = @code.strip
TOKEN_TYPES.each do |type, re|
if @code =~ /\A(#{re})/
@code = @code[$1.length..-1]
return Token.new(type, $1)
end
end
raise RuntimeError.new("Couldn't find token for #{@code.inspect}")
end
end
Token = Struct.new(:type, :value)
tokens = Tokenizer.new(File.read('source')).tokenize
puts tokens
# Parser (takes the tokens and turns them into an intermediate representation)
class Parser
end
# tree = Parser.new(tokens).parse
# puts tree
# Code Generator (takes the intermediate representation and generates new code from it)
class Generator
def generate(node)
case node
when DefNode
"function %s(%s) { return %s }" % [
node.name,
node.argument_names.join(','),
generate(node.body)
]
when CallNode
"%s(%s)" % [
node.name,
node.argument_expressions.map do |arg_exp|
generate(arg_exp)
end.join(",")
]
when VariableNode
node.value
when IntegerNode
node.value
else
raise RuntimeError.new("Unexpected Node Type #{node.class}")
end
end
end
# puts Generator.new.generate(tree)