citrus-compiler 0.8.1 → 0.8.2

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 CHANGED
@@ -32,14 +32,14 @@ As you can see, very ruby-like.
32
32
 
33
33
  Citrus requires the following libraries:
34
34
 
35
- * LLVM 2.8 compiled with shared libraries
35
+ * LLVM 2.9 compiled with shared libraries
36
36
  * On Mac OS X, the quickest way is to use `brew install llvm --shared`
37
37
  * On Linux, there are usually pre-compiled packages
38
38
  * Ruby
39
39
  * Treetop
40
40
  * Ruby LLVM (currently building the source from Jeremy's next branch is required)
41
41
 
42
- Everything except LLVM is installed when running `gem install citrus-compiler`
42
+ Everything except LLVM (and presently, ruby-llvm) is installed when running `gem install citrus-compiler`
43
43
 
44
44
  == Running
45
45
 
@@ -22,13 +22,15 @@ module Citrus
22
22
  end
23
23
 
24
24
  def range(first, last, full)
25
- ival = INT.from_i(-1)
25
+ ival = nil
26
26
  ary = @builder.alloca(LLVM::Array(INT, 0))
27
- iteration = builder.alloca(INT)
28
- builder.store(first, iteration)
29
- index = builder.alloca(INT)
30
- builder.store(INT.from_i(0), index)
27
+ iteration = @builder.alloca(INT)
28
+ @builder.store(first, iteration)
29
+ index = @builder.alloca(INT)
30
+ @builder.store(INT.from_i(0), index)
31
+ ib = @builder.insert_block
31
32
  self.preploop(:while)
33
+ lb = @builder.insert_block
32
34
  self.while(self.compare(full ? :<= : :<, @builder.load(iteration), last)) do |gw|
33
35
  ival = gw.builder.load(index)
34
36
  val = gw.builder.load(iteration)
@@ -37,7 +39,8 @@ module Citrus
37
39
  gw.builder.store(gw.equate(:+, val, gw.number(1)), iteration)
38
40
  gw.builder.store(gw.equate(:+, ival, gw.number(1)), index)
39
41
  end
40
- return Array.new(ary, :length => self.equate(:+, ival, self.number(1)))
42
+ ival = @builder.load(index)
43
+ return Array.new(ary, :length => ival)
41
44
  end
42
45
 
43
46
  def string(value)
@@ -56,6 +59,10 @@ module Citrus
56
59
  BOOL.from_i(value ? 1 : 0)
57
60
  end
58
61
 
62
+ def negate(value)
63
+ @builder.neg(value)
64
+ end
65
+
59
66
  def not(value)
60
67
  @builder.not(value)
61
68
  end
@@ -1,31 +1,37 @@
1
1
  module Citrus
2
- class SyntaxError < RuntimeError
2
+ class SyntaxError < ScriptError
3
3
  def initialize
4
4
  line = $parser.failure_line
5
5
  col = $parser.failure_column
6
6
  str = $parser.input.lines.to_a[line-1]
7
7
  str = str.slice(col-1, str.length).delete($/)
8
8
  str = "file end" if str.empty?
9
- puts $parser.failure_reason
10
9
  super("Unexpected #{str} at #{line}:#{col}.")
11
10
  end
12
11
  end
13
12
 
14
- class NameError < RuntimeError
13
+ class StandardError < RuntimeError
14
+ def initialize(message)
15
+ line = $parser.input.line_of($pindex)
16
+ col = $parser.input.column_of($pindex)
17
+ super("#{message} at #{line}:#{col}.")
18
+ end
19
+ end
20
+
21
+ class NameError < StandardError
15
22
  def initialize(name, index=nil, ff=false)
16
- index ||= $parser.input.index(name)
17
- line = $parser.input.line_of(index)
18
- col = $parser.input.column_of(index)
19
- super("Undefined #{ff ? "" : "local variable or "}function '#{name}' at #{line}:#{col}.")
23
+ super("Undefined #{ff ? "" : "local variable or "}function '#{name}")
20
24
  end
21
25
  end
22
26
 
23
27
  class NotFoundError < StandardError
24
28
  def initialize(file)
25
- super("No such file or directory - #{file}.")
29
+ super("No such file or directory - #{file}")
26
30
  end
27
31
  end
28
32
 
33
+ class ArgumentError < StandardError; end
34
+
29
35
  def self.error(error)
30
36
  puts("#{error.message} (#{error.class.to_s.split('::').last})")
31
37
  exit(1)
data/lib/citrus/nodes.rb CHANGED
@@ -5,6 +5,7 @@ module Citrus
5
5
  end
6
6
 
7
7
  def codegen(context)
8
+ $pindex = self.interval.first
8
9
  end
9
10
  end
10
11
  Node = Treetop::Runtime::SyntaxNode
@@ -53,6 +54,18 @@ module Citrus
53
54
  end
54
55
  end
55
56
 
57
+ class Neg < Node
58
+ def codegen(g)
59
+ g.negate(object.codegen(g))
60
+ end
61
+ end
62
+
63
+ class Not < Node
64
+ def codegen(g)
65
+ g.not(object.codegen(g))
66
+ end
67
+ end
68
+
56
69
  class Require < Node
57
70
  def codegen(g)
58
71
  file = string.value
@@ -72,7 +85,7 @@ module Citrus
72
85
  begin
73
86
  g.call(func.value, *arg_values)
74
87
  rescue
75
- Citrus.error(NameError.new(func.value, self.interval.first, true))
88
+ Citrus.error(NameError.new(func.value, true))
76
89
  end
77
90
  end
78
91
  end
@@ -124,7 +137,8 @@ module Citrus
124
137
  fb = g.block do |gb|
125
138
  else_expressions.each { |e| e.codegen(gb) }
126
139
  end
127
- g.condition(condition.codegen(g).last, tb, fb, elfs)
140
+ cond = condition.is_a?(Expression) ? condition.codegen(g).last : condition.codegen(g)
141
+ g.condition(cond, tb, fb, elfs)
128
142
  end
129
143
  end
130
144
 
@@ -194,7 +208,7 @@ module Citrus
194
208
  begin
195
209
  g.call(value)
196
210
  rescue NoMethodError
197
- Citrus.error(NameError.new(value, self.interval.first))
211
+ Citrus.error(NameError.new(value))
198
212
  end
199
213
  end
200
214
  end
@@ -208,6 +222,11 @@ module Citrus
208
222
 
209
223
  class RangeNode < Node
210
224
  def codegen(g)
225
+ fval = first.codegen(g)
226
+ lval = last.codegen(g).last
227
+ unless LLVM::Type(fval) == INT.type && LLVM::Type(lval) == INT.type
228
+ Citrus.error(ArgumentError.new("Bad value for range"))
229
+ end
211
230
  g.range(first.codegen(g), last.codegen(g).last, self.full?)
212
231
  end
213
232
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: citrus-compiler
3
3
  version: !ruby/object:Gem::Version
4
- hash: 61
4
+ hash: 59
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 8
9
- - 1
10
- version: 0.8.1
9
+ - 2
10
+ version: 0.8.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Mac Malone
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-03 00:00:00 Z
18
+ date: 2011-05-04 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: treetop