oryx 0.3.1 → 0.3.7

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.md CHANGED
@@ -16,6 +16,14 @@ C-Flat to x86 compiler.
16
16
  + Oryx 0.3.1
17
17
  + Abstract Syntax Tree defined and generated
18
18
  + Fixed Travis errors by pre-compiling LLVM shared library
19
+ - 8 May 13
20
+ + Oryx 0.3.7
21
+ + Added mutable values
22
+ + Introduced negation of integers
23
+ + `and` and `or` code generation
24
+ + Improved UX
25
+ + Debug mode
26
+
19
27
 
20
28
  ## C-Flat
21
29
  C-Flat is a working subset of C designed for use in compilers courses. C-flat includes expressions, basic control flow, recursive functions, and strict type checking. It is object-compatible with ordinary C and thus can take advantage of the standard C library, at least when using limited types.
@@ -7,6 +7,7 @@ C-Flat is a working subset of C designed for use in compilers courses. C-Flat in
7
7
  - `boolean`
8
8
  - `char`
9
9
  - `else`
10
+ - `false`
10
11
  - `if`
11
12
  - `int`
12
13
  - `print`
@@ -29,6 +30,7 @@ C-Flat ignores whitespace (beyond separating identifiers).
29
30
  C-Flat includes many of the arithmetic operators found in C. Here they are enumerated with precedence.
30
31
 
31
32
  ( ) grouping ^ (highest precedence)
33
+ - negation |
32
34
  * / multiplication |
33
35
  + - addition |
34
36
  < <= >= == != comparison |
@@ -1,6 +1,6 @@
1
- # Fibonacci Example
1
+ # Recursive Fibonacci Example
2
2
 
3
- Source Code (`test/data/fib.c`)
3
+ ## Source Code (`test/data/fib.c`)
4
4
 
5
5
  int fib(int x) {
6
6
  if (x < 2) return 1;
@@ -11,5 +11,255 @@ Source Code (`test/data/fib.c`)
11
11
  return fib(5);
12
12
  }
13
13
 
14
- Parse Tree
14
+ ## Command
15
+
16
+ oryx -v fib.c -o fib.out
17
+
18
+ ## Tokens
19
+ File: `fib.lex`
20
+
21
+ TYPE | VALUE | POSITION
22
+ -----------------------------------
23
+ INT 1,0
24
+ IDENT fib 1,4
25
+ LPAREN 1,7
26
+ INT 1,8
27
+ IDENT x 1,12
28
+ RPAREN 1,13
29
+ LCURLY 1,15
30
+ IF 2,2
31
+ LPAREN 2,5
32
+ IDENT x 2,6
33
+ LE 2,8
34
+ NUM 2 2,10
35
+ RPAREN 2,11
36
+ RETURN 2,13
37
+ NUM 1 2,20
38
+ SEMI 2,21
39
+ ELSE 3,2
40
+ RETURN 3,7
41
+ IDENT fib 3,14
42
+ LPAREN 3,17
43
+ IDENT x 3,18
44
+ MINUS 3,19
45
+ NUM 1 3,20
46
+ RPAREN 3,21
47
+ PLUS 3,22
48
+ IDENT fib 3,23
49
+ LPAREN 3,26
50
+ IDENT x 3,27
51
+ MINUS 3,28
52
+ NUM 2 3,29
53
+ RPAREN 3,30
54
+ SEMI 3,31
55
+ RCURLY 4,0
56
+ INT 6,0
57
+ IDENT main 6,4
58
+ LPAREN 6,8
59
+ RPAREN 6,9
60
+ LCURLY 6,11
61
+ RETURN 7,2
62
+ IDENT fib 7,9
63
+ LPAREN 7,12
64
+ NUM 8 7,13
65
+ RPAREN 7,14
66
+ SEMI 7,15
67
+ RCURLY 8,0
68
+ EOS
69
+
70
+ ## Parse Tree
71
+ Files: `fib.dot`, `fib.jpg`
72
+
73
+ Command: `dot -Tjpeg fib.dot -o fib.jpg`
74
+
15
75
  ![Parse Tree](img/fib_parse.jpg)
76
+
77
+ ## LLVM IR
78
+ ![main function](img/cfgmain.jpg)
79
+ ![fib function](img/cfgfib.jpg)
80
+
81
+ File: `fib.ll`
82
+
83
+ ; ModuleID = 'Oryx JIT'
84
+
85
+ define i32 @fib(i32 %x) {
86
+ entry:
87
+ %x1 = alloca i32
88
+ store i32 %x, i32* %x1
89
+ br label %code_block
90
+
91
+ code_block: ; preds = %entry
92
+ %x2 = load i32* %x1
93
+ %0 = icmp slt i32 %x2, 2
94
+ %booltmp = sext i1 %0 to i32
95
+ %ifcond = icmp ne i32 %booltmp, 0
96
+ br i1 %ifcond, label %then, label %else
97
+
98
+ then: ; preds = %code_block
99
+ br label %merge
100
+
101
+ else: ; preds = %code_block
102
+ %x3 = load i32* %x1
103
+ %subtmp = sub i32 %x3, 1
104
+ %calltmp = call i32 @fib(i32 %subtmp)
105
+ %x4 = load i32* %x1
106
+ %subtmp5 = sub i32 %x4, 2
107
+ %calltmp6 = call i32 @fib(i32 %subtmp5)
108
+ %addtmp = add i32 %calltmp, %calltmp6
109
+ br label %merge
110
+
111
+ merge: ; preds = %else, %then
112
+ %iftmp = phi i32 [ 1, %then ], [ %addtmp, %else ]
113
+ br label %phi_bb
114
+
115
+ phi_bb: ; preds = %merge
116
+ %iftmp7 = phi i32 [ %iftmp, %merge ]
117
+ ret i32 %iftmp7
118
+ }
119
+
120
+ define i32 @main() {
121
+ entry:
122
+ br label %code_block
123
+
124
+ code_block: ; preds = %entry
125
+ %calltmp = call i32 @fib(i32 8)
126
+ br label %phi_bb
127
+
128
+ phi_bb: ; preds = %code_block
129
+ %iftmp = phi i32 [ %calltmp, %code_block ]
130
+ ret i32 %iftmp
131
+ }
132
+
133
+ ## x86
134
+ File: `fib.s`
135
+
136
+ .section __TEXT,__text,regular,pure_instructions
137
+ .globl _fib
138
+ .align 4, 0x90
139
+ _fib: ## @fib
140
+ Ltmp2:
141
+ ## BB#0: ## %entry
142
+ pushq %rbx
143
+ Ltmp3:
144
+ subq $16, %rsp
145
+ Ltmp4:
146
+ Ltmp5:
147
+ movl %edi, 12(%rsp)
148
+ movl $-1, %eax
149
+ cmpl $2, 12(%rsp)
150
+ movl $0, %ecx
151
+ cmovll %eax, %ecx
152
+ movl $1, %eax
153
+ testl %ecx, %ecx
154
+ jne LBB0_2
155
+ ## BB#1: ## %else
156
+ movl 12(%rsp), %edi
157
+ decl %edi
158
+ callq _fib
159
+ movl %eax, %ebx
160
+ movl 12(%rsp), %edi
161
+ addl $-2, %edi
162
+ callq _fib
163
+ addl %ebx, %eax
164
+ LBB0_2: ## %phi_bb
165
+ addq $16, %rsp
166
+ popq %rbx
167
+ ret
168
+ Ltmp6:
169
+ Leh_func_end0:
170
+
171
+ .globl _main
172
+ .align 4, 0x90
173
+ _main: ## @main
174
+ Ltmp8:
175
+ ## BB#0: ## %entry
176
+ pushq %rax
177
+ Ltmp9:
178
+ movl $8, %edi
179
+ callq _fib
180
+ popq %rdx
181
+ ret
182
+ Ltmp10:
183
+ Leh_func_end1:
184
+
185
+
186
+ .subsections_via_symbols
187
+ .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
188
+ Ltmp11:
189
+ EH_frame0:
190
+ Ltmp13 = (Ltmp12-EH_frame0)-4 ## CIE Length
191
+ .long Ltmp13
192
+ .long 0 ## CIE ID Tag
193
+ .byte 1 ## DW_CIE_VERSION
194
+ .ascii "zR" ## CIE Augmentation
195
+ .byte 0
196
+ .byte 1 ## CIE Code Alignment Factor
197
+ .byte 120 ## CIE Data Alignment Factor
198
+ .byte 16 ## CIE Return Address Column
199
+ .byte 1 ## Augmentation Size
200
+ .byte 16 ## FDE Encoding = indirect pcrel sdata8
201
+ .byte 12 ## DW_CFA_def_cfa
202
+ .byte 7 ## Reg 7
203
+ .byte 8 ## Offset 8
204
+ .byte 144 ## DW_CFA_offset + Reg(16)
205
+ .byte 1 ## Offset 1
206
+ .align 2
207
+ Ltmp12:
208
+ .globl _fib.eh
209
+ _fib.eh:
210
+ Ltmp16 = (Ltmp15-Ltmp14)-0 ## FDE Length
211
+ .long Ltmp16
212
+ Ltmp14:
213
+ Ltmp17 = (Ltmp14-EH_frame0)-0 ## FDE CIE Offset
214
+ .long Ltmp17
215
+ Ltmp18:
216
+ Ltmp19 = Ltmp2-Ltmp18 ## FDE initial location
217
+ .quad Ltmp19
218
+ Ltmp20 = (Ltmp6-Ltmp2)-0 ## FDE address range
219
+ .quad Ltmp20
220
+ .byte 0 ## Augmentation size
221
+ .byte 4 ## DW_CFA_advance_loc4
222
+ Ltmp21 = Ltmp3-Ltmp2
223
+ .long Ltmp21
224
+ .byte 14 ## DW_CFA_def_cfa_offset
225
+ .byte 16 ## Offset 16
226
+ .byte 4 ## DW_CFA_advance_loc4
227
+ Ltmp22 = Ltmp4-Ltmp3
228
+ .long Ltmp22
229
+ .byte 14 ## DW_CFA_def_cfa_offset
230
+ .byte 32 ## Offset 32
231
+ .byte 4 ## DW_CFA_advance_loc4
232
+ Ltmp23 = Ltmp5-Ltmp4
233
+ .long Ltmp23
234
+ .byte 131 ## DW_CFA_offset + Reg(3)
235
+ .byte 2 ## Offset 2
236
+ .align 3
237
+ Ltmp15:
238
+ .globl _main.eh
239
+ _main.eh:
240
+ Ltmp26 = (Ltmp25-Ltmp24)-0 ## FDE Length
241
+ .long Ltmp26
242
+ Ltmp24:
243
+ Ltmp27 = (Ltmp24-EH_frame0)-0 ## FDE CIE Offset
244
+ .long Ltmp27
245
+ Ltmp28:
246
+ Ltmp29 = Ltmp8-Ltmp28 ## FDE initial location
247
+ .quad Ltmp29
248
+ Ltmp30 = (Ltmp10-Ltmp8)-0 ## FDE address range
249
+ .quad Ltmp30
250
+ .byte 0 ## Augmentation size
251
+ .byte 4 ## DW_CFA_advance_loc4
252
+ Ltmp31 = Ltmp9-Ltmp8
253
+ .long Ltmp31
254
+ .byte 14 ## DW_CFA_def_cfa_offset
255
+ .byte 16 ## Offset 16
256
+ .align 3
257
+ .align 3
258
+ Ltmp25:
259
+
260
+ ## Return Value
261
+
262
+ $ echo $?
263
+ 34
264
+
265
+
Binary file
Binary file
@@ -7,8 +7,9 @@
7
7
  - Produce tokens from source code (Oryx 0.1.1)
8
8
  - Create parse tree from token stream (Oryx 0.2.1)
9
9
  - Symbol Table working (Oryx 0.2.7)
10
- - Translate parse tree into AST (Oryx ?.?.?)
11
- - Emit LLVM intermediate code by walking AST (Oryx ?.?.?)
10
+ - Translate parse tree into AST (Oryx 0.3.1)
11
+ - Emit LLVM intermediate code by walking AST (Oryx 0.3.7)
12
+ - Loops and Printing (Oryx ?.?.?)
12
13
  - Implement Semantic Analysis (Oryx ?.?.?)
13
14
  - Use LLVM optimizations (Oryx ?.?.?)
14
15
  - Improved error handling (Oryx ?.?.?)
@@ -7,6 +7,14 @@ module Oryx
7
7
  value :value, Integer
8
8
  end
9
9
 
10
+ class Cstring < Expression
11
+ value :value, String
12
+ end
13
+
14
+ class BoolConst < Expression
15
+ value :value, Symbol
16
+ end
17
+
10
18
  class Type < Expression
11
19
  value :t, String
12
20
  end
@@ -21,6 +29,12 @@ module Oryx
21
29
  child :right, Expression
22
30
  end
23
31
 
32
+ class Uniary < Expression
33
+ child :right, Expression
34
+ end
35
+
36
+ class Neg < Uniary; end
37
+
24
38
  class Initialization < Expression
25
39
  value :name, String
26
40
  child :right, Expression
@@ -63,8 +77,10 @@ module Oryx
63
77
  class GEQ < Binary; end
64
78
  class LE < Binary; end
65
79
  class LEQ < Binary; end
66
- class EQ < Binary; end
80
+ class EQ < Binary; end
67
81
  class NEQ < Binary; end
82
+ class And < Binary; end
83
+ class Or < Binary; end
68
84
 
69
85
  class Return < Expression
70
86
  child :right, Expression
@@ -17,6 +17,7 @@ module Oryx
17
17
  super
18
18
  @module = RLTK::CG::Module.new('Oryx JIT')
19
19
  @st = SymbolTable.new
20
+ @branch_needed = true
20
21
  end
21
22
 
22
23
  def begin ast
@@ -32,14 +33,19 @@ module Oryx
32
33
  param_types = parameter_types node.params
33
34
  return_type = visit node.return_type
34
35
  fun = @module.functions.add(node.i, return_type, param_types)
35
- node.params.params.each {|p| visit p}
36
36
  param_names = parameter_names node.params
37
37
  param_names.each_with_index do |name, i|
38
- st.update name.to_sym, fun.params[i]
38
+ fun.params[i].name = name
39
39
  end
40
40
  end
41
-
42
- ret (visit node.body, at: fun.blocks.append('entry'))
41
+ build(fun.blocks.append('entry')) do
42
+ fun.params.each do |param|
43
+ loc = alloca RLTK::CG::NativeIntType, param.name
44
+ st.insert param.name, loc
45
+ store param, loc
46
+ end
47
+ ret ( visit node.body )
48
+ end
43
49
  st.exit_scope
44
50
 
45
51
  returning(fun) { fun.verify }
@@ -54,15 +60,35 @@ module Oryx
54
60
 
55
61
  on Variable do |node|
56
62
  begin
57
- st.lookup node.name.to_sym
63
+ self.load (st.lookup node.name.to_sym), node.name
58
64
  rescue SymbolTableError => e
59
65
  STDERR.puts e.message, "Attempting to continue without this value."
60
66
  end
61
67
  end
62
68
 
63
69
  on CodeBlock do |node|
64
- a = node.statements.map {|s| visit s}
65
- a.first
70
+ st.enter_scope
71
+ start = current_block
72
+ fun = start.parent
73
+ b = fun.blocks.append('code_block')
74
+ value = ''
75
+ next_b = [b]
76
+ node.statements.each_with_index do |s, i|
77
+ value, new_b = visit s, at: next_b.last, rcb: true
78
+ if new_b != b
79
+ build(next_b.last) { br new_b} if @branch_needed and i != node.statements.count-1
80
+ @branch_needed = true
81
+ next_b << new_b
82
+ end
83
+ end
84
+
85
+
86
+ phi_bb = fun.blocks.append('phi_bb', self)
87
+ phi_inst = build(phi_bb) { phi RLTK::CG::NativeIntType, { next_b.last=> value, next_b.last => value}, 'iftmp' }
88
+ build(start) { br b }
89
+ build(next_b.last) { br phi_bb }
90
+ st.exit_scope
91
+ returning(phi_inst) { target phi_bb }
66
92
  end
67
93
 
68
94
  on Return do |node|
@@ -85,6 +111,8 @@ module Oryx
85
111
  when LEQ then integer_cast(icmp(:sle, left, right), RLTK::CG::NativeIntType, 'booltmp')
86
112
  when EQ then integer_cast(icmp(:eq, left, right), RLTK::CG::NativeIntType, 'booltmp')
87
113
  when NEQ then integer_cast(icmp(:ne, left, right), RLTK::CG::NativeIntType, 'booltmp')
114
+ when And then integer_cast((build_inst :and, left, right), RLTK::CG::NativeIntType, 'andtmp')
115
+ when Or then integer_cast((build_inst :or, left, right), RLTK::CG::NativeIntType, 'ortmp')
88
116
  end
89
117
  end
90
118
 
@@ -92,11 +120,37 @@ module Oryx
92
120
  RLTK::CG::NativeInt.new(node.value)
93
121
  end
94
122
 
123
+ on BoolConst do |node|
124
+ int_val = (node.value == :true) ? 1 : 0
125
+ RLTK::CG::Int1.new(int_val)
126
+ end
127
+
128
+ on Neg do |node|
129
+ right = visit node.right
130
+ sub(ZERO, right, 'negtmp')
131
+ end
132
+
95
133
  on GInitialization do |node|
96
134
  name = node.name.to_sym
97
135
  value = visit node.right
136
+ loc = alloca RLTK::CG::NativeIntType, name.to_s
137
+ puts "#{name} -> #{loc}"
138
+ begin
139
+ st.insert(name, loc)
140
+ rescue SymbolTableError => e
141
+ STDERR.puts e.message, "Continuing processing without modifying the symbol table"
142
+ end
143
+ puts "#{name} -> #{st.lookup name}"
144
+ store value, loc
145
+ end
146
+
147
+ on Initialization do |node|
148
+ name = node.name.to_sym
149
+ value = visit node.right
150
+ loc = alloca RLTK::CG::NativeIntType, name.to_s
98
151
  begin
99
- st.insert(name, value)
152
+ st.insert(name, loc)
153
+ store value, loc
100
154
  rescue SymbolTableError => e
101
155
  STDERR.puts e.message, "Continuing processing without modifying the symbol table"
102
156
  end
@@ -104,8 +158,9 @@ module Oryx
104
158
 
105
159
  on GDeclaration do |node|
106
160
  name = node.name.to_sym
161
+ loc = alloca RLTK::CG::NativeIntType, name.to_s
107
162
  begin
108
- st.insert name
163
+ st.insert name, loc
109
164
  rescue SymbolTableError => e
110
165
  STDERR.puts e.message, "Continuing processing without modifying the symbol table"
111
166
  end
@@ -113,8 +168,9 @@ module Oryx
113
168
 
114
169
  on Declaration do |node|
115
170
  name = node.name.to_sym
171
+ loc = alloca RLTK::CG::NativeIntType, name.to_s
116
172
  begin
117
- st.insert name
173
+ st.insert name, loc
118
174
  rescue SymbolTableError => e
119
175
  STDERR.puts e.message, "Continuing processing without modifying the symbol table"
120
176
  end
@@ -124,7 +180,9 @@ module Oryx
124
180
  value = visit node.right
125
181
  name = node.name.to_sym
126
182
  begin
127
- st.update name, value
183
+ loc = st.lookup name
184
+ store value, loc
185
+ self.load loc, name.to_s
128
186
  rescue SymbolTableError => e
129
187
  STDERR.puts e.message, "Continuing processing witout modifying the symbol table"
130
188
  end
@@ -155,6 +213,7 @@ module Oryx
155
213
  build(start_bb) { cond cond_val, then_bb, else_bb }
156
214
  build(new_then_bb) { br merge_bb }
157
215
  build(new_else_bb) { br merge_bb }
216
+ @branch_needed = false
158
217
  returning(phi_inst) { target merge_bb }
159
218
  end
160
219
 
@@ -4,12 +4,15 @@ require 'pathname'
4
4
  module Oryx
5
5
  class Options
6
6
  DEFAULT_INPUT = ""
7
- DEFAULT_OUTPUT = Pathname.new("/tmp/oryx-output")
7
+ DEFAULT_OUTPUT = Pathname.new "a.out"
8
8
 
9
9
  def initialize(argv)
10
- @config = {output: DEFAULT_OUTPUT,
11
- input: DEFAULT_INPUT}
10
+ @config = {output: DEFAULT_OUTPUT,
11
+ input: DEFAULT_INPUT,
12
+ verbose: false}
13
+
12
14
  parse(argv)
15
+
13
16
  begin
14
17
  input = Pathname.new(argv.pop).expand_path
15
18
  @config[:input] = input
@@ -37,6 +40,9 @@ module Oryx
37
40
  opts.on("-o", "--output FILE", String, "Output filename") do |path|
38
41
  @config[:output] = Pathname.new(path).expand_path
39
42
  end
43
+ opts.on("-v", "--verbose", "Auxilary information about compilation process") do
44
+ @config[:verbose] = true
45
+ end
40
46
 
41
47
  begin
42
48
  argv = ["-h"] if argv.empty?
@@ -94,7 +94,7 @@ module Oryx
94
94
  clause('e SEMI') { |e, _| e }
95
95
  clause('if_statement') { |i| i}
96
96
  clause('WHILE LPAREN e RPAREN code_block') {|_,_,e,_,c| While.new(e,c) }
97
- clause('type_spec IDENT ASSIGN e SEMI') { |t, e0, _, e1, _| Initialization.new t, e0, e1 }
97
+ clause('type_spec IDENT ASSIGN e SEMI') { |t, e0, _, e1, _| Initialization.new e0, e1, t }
98
98
  clause('type_spec IDENT SEMI') { |t, i, _ | Declaration.new i,t }
99
99
  end
100
100
 
@@ -118,6 +118,7 @@ module Oryx
118
118
  clause('constant') { |c| c }
119
119
  clause('IDENT ASSIGN e') { |e0, _, e1| Assign.new e0, e1 }
120
120
 
121
+ clause('MINUS e') { |_, e| Neg.new(e) }
121
122
  clause('e PLUS e') { |e0, _, e1| Add.new(e0, e1) }
122
123
  clause('e MINUS e') { |e0, _, e1| Sub.new(e0, e1) }
123
124
  clause('e TIMES e') { |e0, _, e1| Mul.new(e0, e1) }
@@ -128,13 +129,16 @@ module Oryx
128
129
  clause('e LEQ e') { |e0, _, e1| LEQ.new(e0, e1) }
129
130
  clause('e EQ e') { |e0, _, e1| EQ.new(e0, e1) }
130
131
  clause('e NEQ e') { |e0, _, e1| NEQ.new(e0, e1) }
132
+ clause('e AND e') { |e0, _, e1| And.new(e0, e1) }
133
+ clause('e OR e') { |e0, _, e1| Or.new(e0, e1) }
131
134
 
135
+ clause('TRUE') { |t| BoolConst.new (:true) }
136
+ clause('FALSE') { |t| BoolConst.new (:false) }
132
137
 
133
138
  clause('RETURN e') { |_, e| Return.new e }
134
139
 
135
140
  clause('IDENT LPAREN opt_arg_list RPAREN') { |i, _, oal, _| Call.new(i, oal) }
136
141
  end
137
142
 
138
- finalize explain: 'explain.out'
139
143
  end
140
144
  end
@@ -9,30 +9,68 @@ module Oryx
9
9
  @options = Options.new argv
10
10
  @input_filename = @options.input
11
11
  @output_filename = @options.output
12
+ @verbose = @options.verbose
12
13
  end
13
14
 
14
15
  def run
15
16
  puts "input: #{input_filename}"
16
17
  puts "output: #{output_filename}"
17
- print "lexing".blue+"."*17
18
- l = Lexer.new
19
- output_filename.open('w:UTF-8') { |f| f.write(tabularize_output l.lex_file(input_filename.to_s)) }
20
- puts "complete".green
21
18
 
22
- p = Parser.new
23
- ast = p.parse(l.lex_file(input_filename.to_s), parse_tree: 'tree.dot', verbose: 'parse.out')
19
+ tokens = lex input_filename
20
+ ast = parse tokens
21
+ generate ast
22
+ end
23
+
24
+ private
25
+ def lex code
26
+ STDERR.print "lexing".blue+"."*17
27
+ l = Lexer.new
28
+ tokens = l.lex_file(code)
29
+ output("lex") { tabularize_output tokens }
30
+ STDERR.puts "complete".green
31
+ tokens
32
+ end
24
33
 
25
- c = Contractor.new
26
- c.begin ast
34
+ def parse tokens=[]
35
+ STDERR.print "parsing".blue+"."*17
36
+ finalize_parser
37
+ p = Parser.new
38
+ parse_flags = Hash.new
39
+ parse_flags.merge!( {
40
+ parse_tree: name("parse.dot"),
41
+ verbose: name("parse.log")
42
+ }
43
+ ) if @verbose
44
+ ast = p.parse(tokens, parse_flags)
45
+ STDERR.puts "complete".green
46
+ ast
47
+ end
27
48
 
28
- output_ir c.module
49
+ def generate ast
50
+ STDERR.print "generating".blue+"."*17
51
+ c = Contractor.new
52
+ c.begin ast
29
53
 
30
- translate_to_assembly
31
- create_executable
54
+ output_ir c.module
32
55
 
33
- end
56
+ translate_to_assembly
57
+ create_executable
58
+ STDERR.puts "complete".green
59
+ end
60
+
61
+ def finalize_parser
62
+ if 0 == Parser.class_eval { @states.length }
63
+ if @verbose
64
+ explain_file = name("parse")
65
+ Parser.class_eval do
66
+ finalize explain: explain_file
67
+ end
68
+ else
69
+ Parser.class_eval { finalize }
70
+ end
71
+ end
72
+ end
34
73
 
35
- private
36
74
  def tabularize_output tokens
37
75
  s = table_header
38
76
  tokens.each do |t|
@@ -51,6 +89,17 @@ module Oryx
51
89
  input_filename.to_s.split('.').first
52
90
  end
53
91
 
92
+ def name extension
93
+ "#{base_name}.#{extension.to_s}"
94
+ end
95
+
96
+ def output extension
97
+ if @verbose
98
+ file = Pathname.new name(extension)
99
+ file.open('w:UTF-8') { |f| f.write (yield) }
100
+ end
101
+ end
102
+
54
103
  def output_ir ir_module
55
104
  ir_module.verify
56
105
  orig_stderr = $stderr.clone
@@ -60,11 +109,11 @@ module Oryx
60
109
  end
61
110
 
62
111
  def translate_to_assembly
63
- `llc -disable-cfi #{base_name}.ll`
112
+ `llc -disable-cfi #{name "ll"}`
64
113
  end
65
114
 
66
115
  def create_executable
67
- `gcc #{base_name}.s -o #{base_name}.out`
116
+ `gcc #{base_name}.s -o #{output_filename}`
68
117
  end
69
118
 
70
119
  def table_header
@@ -1,3 +1,3 @@
1
1
  module Oryx
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.7"
3
3
  end
@@ -0,0 +1,14 @@
1
+ int test_and(int a, int b, int c){
2
+ if(a < b && b > c)
3
+ return 5;
4
+ else
5
+ return 4;
6
+ }
7
+
8
+ int main(){
9
+ int a = 7;
10
+ int b = 8;
11
+ int c = 1;
12
+
13
+ return test_and(a, b, c);
14
+ }
@@ -0,0 +1,14 @@
1
+ int test_and(int a, int b, int c){
2
+ if(a < b && b > c)
3
+ return 5;
4
+ else
5
+ return 4;
6
+ }
7
+
8
+ int main(){
9
+ int a = 7;
10
+ int b = 8;
11
+ int c = 1;
12
+
13
+ return test_and(c,a,b);
14
+ }
@@ -0,0 +1,9 @@
1
+ int fun_2(int a, int b){
2
+ int c;
3
+ c = a + b;
4
+ return c;
5
+ }
6
+
7
+ int main(){
8
+ return fun_2(12,13);
9
+ }
@@ -0,0 +1,11 @@
1
+ int fun_3(int a, int b) {
2
+ int c = a*a;
3
+ int d = 2*a*b;
4
+ int e = b*b;
5
+ int sum = c + d + e;
6
+ return sum;
7
+ }
8
+
9
+ int main(){
10
+ return fun_3(5,6);
11
+ }
@@ -0,0 +1,9 @@
1
+ int f(int a){
2
+ return a+1;
3
+ }
4
+
5
+ int main(){
6
+ int a = 7;
7
+ return f(a);
8
+ }
9
+
@@ -1,5 +1,6 @@
1
- int a = 7;
1
+ int a;
2
2
 
3
3
  int main(){
4
+ a = 7;
4
5
  return a;
5
6
  }
@@ -2,7 +2,7 @@ int a = 8;
2
2
  int b = 13;
3
3
 
4
4
  int main(){
5
- if(a < b){
5
+ if(a > b){
6
6
  a = a + b;
7
7
  b = 1;
8
8
  if (b < a)
@@ -0,0 +1,15 @@
1
+ int a = 8;
2
+ int b = 13;
3
+
4
+ int main(){
5
+ if(a < b){
6
+ a = a + b;
7
+ b = 1;
8
+ if (b > a)
9
+ return b;
10
+ else
11
+ return a;
12
+ }
13
+ else
14
+ return a;
15
+ }
@@ -0,0 +1,20 @@
1
+ int main(){
2
+ int a = 8;
3
+ int b = 13;
4
+ int c;
5
+
6
+ if(a < b){
7
+ c = a;
8
+ }else{
9
+ c = b;
10
+ }
11
+
12
+ if(b < c){
13
+ c = c + b;
14
+ }
15
+ else{
16
+ c = c + a;
17
+ }
18
+
19
+ return c;
20
+ }
@@ -0,0 +1,20 @@
1
+ int main(){
2
+ int a = 8;
3
+ int b = 13;
4
+ int c;
5
+
6
+ if(a < b){
7
+ c = a;
8
+ }else{
9
+ c = b;
10
+ }
11
+
12
+ if(b > c){
13
+ c = c + b;
14
+ }
15
+ else{
16
+ c = c + a;
17
+ }
18
+
19
+ return c;
20
+ }
@@ -0,0 +1,30 @@
1
+ int main(){
2
+ int a = 1;
3
+ int b = 2;
4
+ int c = 3;
5
+ int d = 4;
6
+ int e = 5;
7
+ int f = 6;
8
+ int g = 7;
9
+ int h = 8;
10
+ int j = 9;
11
+ int i = 10;
12
+ int k = 11;
13
+ int l = 12;
14
+ int m = 13;
15
+ int n = 14;
16
+ int o = 15;
17
+ int p = 16;
18
+ int q = 17;
19
+ int r = 18;
20
+ int s = 19;
21
+ int t = 20;
22
+ int u = 21;
23
+ int v = 22;
24
+ int w = 23;
25
+ int x = 24;
26
+ int y = 25;
27
+ int z = 26;
28
+
29
+ return z;
30
+ }
@@ -0,0 +1,9 @@
1
+ int main(){
2
+ int a = 5;
3
+ int b;
4
+ b = 9;
5
+ b = b + a;
6
+ a = a* b;
7
+ b = a - b;
8
+ return a + 2*b;
9
+ }
@@ -0,0 +1,3 @@
1
+ int main(){
2
+ return -1;
3
+ }
@@ -0,0 +1,5 @@
1
+ int main(){
2
+ int a = 1;
3
+ int b = -a - 10;
4
+ return b;
5
+ }
@@ -0,0 +1,6 @@
1
+ int main(){
2
+ int a = 42;
3
+ int b = 8;
4
+ int c = a - -b;
5
+ return c;
6
+ }
@@ -0,0 +1,5 @@
1
+ int main(){
2
+ int a = 13;
3
+
4
+ return ---------a;
5
+ }
@@ -0,0 +1,10 @@
1
+ int test_or(int a, int b, int c){
2
+ if(a < b || b < c)
3
+ return a;
4
+ else
5
+ return c;
6
+ }
7
+
8
+ int main(){
9
+ return test_or(9, -5, 3);
10
+ }
@@ -0,0 +1,10 @@
1
+ int test_or(int a, int b, int c){
2
+ if(a < b || b < c)
3
+ return a;
4
+ else
5
+ return c;
6
+ }
7
+
8
+ int main(){
9
+ return test_or(9, 5, 3);
10
+ }
@@ -8,18 +8,34 @@ module Oryx
8
8
  should_generate_toolchain_output("sub", (-7)%256)
9
9
  should_generate_toolchain_output("mul", 175)
10
10
  should_generate_toolchain_output("div", 2)
11
- should_generate_toolchain_output("gvar_1", 7)
12
- should_generate_toolchain_output("gvar_2", 42)
13
- should_generate_toolchain_output("gvar_3", 15)
11
+ # should_generate_toolchain_output("gvar_1", 7)
12
+ # should_generate_toolchain_output("gvar_2", 42)
13
+ # should_generate_toolchain_output("gvar_3", 15)
14
14
  should_generate_toolchain_output("fun_1", 9)
15
+ should_generate_toolchain_output("fun_2", 25)
16
+ should_generate_toolchain_output("fun_3", 121)
17
+ should_generate_toolchain_output("fun_4", 8)
15
18
  should_generate_toolchain_output("ge", 7)
16
19
  should_generate_toolchain_output("le", 8)
17
20
  should_generate_toolchain_output("leq", 15)
18
21
  should_generate_toolchain_output("geq", 9)
19
22
  should_generate_toolchain_output("eq", 5)
20
23
  should_generate_toolchain_output("neq", 4)
21
- should_generate_toolchain_output("if", 21)
24
+ # should_generate_toolchain_output("if", 1)
25
+ # should_generate_toolchain_output("if_2", 21)
26
+ should_generate_toolchain_output("if_3", 16)
27
+ should_generate_toolchain_output("if_4", 21)
22
28
  should_generate_toolchain_output("fib", 34)
29
+ should_generate_toolchain_output("neg", (-1)%256)
30
+ should_generate_toolchain_output("neg2", (-11)%256)
31
+ should_generate_toolchain_output("neg3", 50)
32
+ should_generate_toolchain_output("neg4", (-13)%256)
33
+ should_generate_toolchain_output("and", 5)
34
+ should_generate_toolchain_output("and2", 4)
35
+ should_generate_toolchain_output("or", 9)
36
+ should_generate_toolchain_output("or2", 3)
37
+ should_generate_toolchain_output("mut", 182)
38
+ should_generate_toolchain_output("long", 26)
23
39
  end
24
40
  end
25
41
  end
@@ -10,25 +10,19 @@ module Oryx
10
10
  teardown_helper base_name
11
11
  end
12
12
 
13
- should "create LLVM IR" do
13
+ should "create files" do
14
14
  path = @directory + "#{@base_name}.ll"
15
15
  assert path.exist?, "#{path} was not created"
16
- end
17
16
 
18
- should "translate IR into Assembly" do
19
17
  path = @directory + "#{@base_name}.s"
20
18
  assert path.exist?, "#{path} was not created"
21
- end
22
19
 
23
- should "create executable" do
24
20
  path = @directory + "#{@base_name}.out"
25
21
  assert path.exist?, "#{path} was not created"
26
22
  assert path.executable?, "#{path} is not an executable"
27
- end
28
23
 
29
- should "return the correct result" do
30
24
  path = @directory + "#{@base_name}.out"
31
- assert_equal return_value, %x[#{path}; echo $?].to_i
25
+ assert_equal return_value, %x[#{path}; echo $?].to_i, "Wrong result returned"
32
26
  end
33
27
  end
34
28
  end
@@ -47,12 +41,15 @@ module Oryx
47
41
  def setup_helper file
48
42
  @directory = Pathname.new "test/data/"
49
43
  @base_name = file
50
- r = Runner.new [(@directory+"#{@base_name}.c")]
44
+ r = Runner.new [(@directory+"#{@base_name}.c"), "-o", (@directory+"#{@base_name}.out").to_s]
51
45
  stfu {r.run}
52
46
  end
53
47
 
54
48
  def teardown_helper file
55
- %w[ll s out].each { |e| (@directory+"#{@base_name}.#{e}").delete }
49
+ %w[ll s out].each do |e|
50
+ path = @directory+"#{@base_name}.#{e}"
51
+ path.delete if path.exist?
52
+ end
56
53
  end
57
54
  end
58
55
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oryx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-29 00:00:00.000000000 Z
12
+ date: 2013-05-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -94,6 +94,8 @@ files:
94
94
  - doc/cflat.md
95
95
  - doc/conclusion.md
96
96
  - doc/fibonacci.md
97
+ - doc/img/cfgfib.jpg
98
+ - doc/img/cfgmain.jpg
97
99
  - doc/img/fib_parse.jpg
98
100
  - doc/intermediate_lang.md
99
101
  - doc/intro.md
@@ -114,20 +116,36 @@ files:
114
116
  - lib/oryx/version.rb
115
117
  - oryx.gemspec
116
118
  - test/data/add.c
119
+ - test/data/and.c
120
+ - test/data/and2.c
117
121
  - test/data/div.c
118
122
  - test/data/eq.c
119
123
  - test/data/fib.c
120
124
  - test/data/fun_1.c
125
+ - test/data/fun_2.c
126
+ - test/data/fun_3.c
127
+ - test/data/fun_4.c
121
128
  - test/data/ge.c
122
129
  - test/data/geq.c
123
130
  - test/data/gvar_1.c
124
131
  - test/data/gvar_2.c
125
132
  - test/data/gvar_3.c
126
133
  - test/data/if.c
134
+ - test/data/if_2.c
135
+ - test/data/if_3.c
136
+ - test/data/if_4.c
127
137
  - test/data/le.c
128
138
  - test/data/leq.c
139
+ - test/data/long.c
129
140
  - test/data/mul.c
141
+ - test/data/mut.c
142
+ - test/data/neg.c
143
+ - test/data/neg2.c
144
+ - test/data/neg3.c
145
+ - test/data/neg4.c
130
146
  - test/data/neq.c
147
+ - test/data/or.c
148
+ - test/data/or2.c
131
149
  - test/data/return.c
132
150
  - test/data/sub.c
133
151
  - test/lib/oryx/error_test.rb
@@ -152,7 +170,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
152
170
  version: '0'
153
171
  segments:
154
172
  - 0
155
- hash: 1968373242303314984
173
+ hash: 2494793455272379608
156
174
  required_rubygems_version: !ruby/object:Gem::Requirement
157
175
  none: false
158
176
  requirements:
@@ -161,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
161
179
  version: '0'
162
180
  segments:
163
181
  - 0
164
- hash: 1968373242303314984
182
+ hash: 2494793455272379608
165
183
  requirements: []
166
184
  rubyforge_project:
167
185
  rubygems_version: 1.8.23
@@ -170,20 +188,36 @@ specification_version: 3
170
188
  summary: Take a program written in C-Flat and convert it to x86 assembly
171
189
  test_files:
172
190
  - test/data/add.c
191
+ - test/data/and.c
192
+ - test/data/and2.c
173
193
  - test/data/div.c
174
194
  - test/data/eq.c
175
195
  - test/data/fib.c
176
196
  - test/data/fun_1.c
197
+ - test/data/fun_2.c
198
+ - test/data/fun_3.c
199
+ - test/data/fun_4.c
177
200
  - test/data/ge.c
178
201
  - test/data/geq.c
179
202
  - test/data/gvar_1.c
180
203
  - test/data/gvar_2.c
181
204
  - test/data/gvar_3.c
182
205
  - test/data/if.c
206
+ - test/data/if_2.c
207
+ - test/data/if_3.c
208
+ - test/data/if_4.c
183
209
  - test/data/le.c
184
210
  - test/data/leq.c
211
+ - test/data/long.c
185
212
  - test/data/mul.c
213
+ - test/data/mut.c
214
+ - test/data/neg.c
215
+ - test/data/neg2.c
216
+ - test/data/neg3.c
217
+ - test/data/neg4.c
186
218
  - test/data/neq.c
219
+ - test/data/or.c
220
+ - test/data/or2.c
187
221
  - test/data/return.c
188
222
  - test/data/sub.c
189
223
  - test/lib/oryx/error_test.rb