flea 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +274 -0
- data/Rakefile +36 -0
- data/VERSION +1 -0
- data/bin/flea +39 -0
- data/examples/guess-the-number.scm +18 -0
- data/flea-language-spec/README.rdoc +3 -0
- data/flea-language-spec/flea-language-spec.yaml +2 -0
- data/flea-language-spec/test-cases/01-display-and-basic-literals/01-display-string-literal.scm +5 -0
- data/flea-language-spec/test-cases/01-display-and-basic-literals/02-display-integer-literal.scm +5 -0
- data/flea-language-spec/test-cases/01-display-and-basic-literals/03-display-boolean-true-literal.scm +5 -0
- data/flea-language-spec/test-cases/01-display-and-basic-literals/04-display-boolean-false-literal.scm +5 -0
- data/flea-language-spec/test-cases/01-display-and-basic-literals/05-display-list-literal-using-quote.scm +5 -0
- data/flea-language-spec/test-cases/01-display-and-basic-literals/06-display-identifier-quoted.scm +5 -0
- data/flea-language-spec/test-cases/02-variables/01-define-with-string.scm +6 -0
- data/flea-language-spec/test-cases/02-variables/02-define-with-integer.scm +6 -0
- data/flea-language-spec/test-cases/02-variables/03-define-with-boolean-true.scm +6 -0
- data/flea-language-spec/test-cases/02-variables/04-define-with-boolean-false.scm +6 -0
- data/flea-language-spec/test-cases/02-variables/05-define-with-list.scm +6 -0
- data/flea-language-spec/test-cases/03-basic-built-in-procedures/01-addition.scm +5 -0
- data/flea-language-spec/test-cases/03-basic-built-in-procedures/02-subtraction.scm +5 -0
- data/flea-language-spec/test-cases/03-basic-built-in-procedures/03-multiplication.scm +5 -0
- data/flea-language-spec/test-cases/03-basic-built-in-procedures/04-division.scm +5 -0
- data/flea-language-spec/test-cases/03-basic-built-in-procedures/05-equality-true-integer.scm +5 -0
- data/flea-language-spec/test-cases/03-basic-built-in-procedures/06-equality-false-integer.scm +5 -0
- data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/01-equal?-true-integer.scm +5 -0
- data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/02-equal?-false-integer.scm +5 -0
- data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/03-equal?-true-string.scm +5 -0
- data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/04-equal?-false-string.scm +5 -0
- data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/05-equal?-true-boolean.scm +5 -0
- data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/06-equal?-false-boolean.scm +5 -0
- data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/07-equal?-true-list.scm +7 -0
- data/flea-language-spec/test-cases/03-basic-built-in-procedures/07-equal?/08-equal?-false-list.scm +7 -0
- data/flea-language-spec/test-cases/04-comma-quoting/01-comma-quoting.scm +5 -0
- data/flea-language-spec/test-cases/05-lambda/01-lambda.scm +5 -0
- data/flea-language-spec/test-cases/05-lambda/02-call-in-place-lambda.scm +5 -0
- data/flea-language-spec/test-cases/05-lambda/03-define-with-lambda.scm +6 -0
- data/flea-language-spec/test-cases/05-lambda/04-define-and-call-lambda.scm +8 -0
- data/flea-language-spec/test-cases/05-lambda/05-lambda-repeated-argument.scm +9 -0
- data/flea-language-spec/test-cases/05-lambda/06-lambda-list-argument.scm +8 -0
- data/flea-language-spec/test-cases/05-lambda/07-lambda-n-or-more-arguments.scm +12 -0
- data/flea-language-spec/test-cases/05-lambda/08-lambda-should-return-last-result.scm +16 -0
- data/flea-language-spec/test-cases/06-if/01-if-true-single-arg.scm +6 -0
- data/flea-language-spec/test-cases/06-if/02-if-false-single-arg.scm +6 -0
- data/flea-language-spec/test-cases/06-if/03-if-true-two-args.scm +7 -0
- data/flea-language-spec/test-cases/06-if/04-if-false-two-args.scm +7 -0
- data/flea-language-spec/test-cases/07-set/01-should-not-set-undefined-variable.scm +5 -0
- data/flea-language-spec/test-cases/07-set/02-set-previously-defined-variable.scm +8 -0
- data/flea-language-spec/test-cases/08-derived-expressions/01-begin/01-begin.scm +8 -0
- data/flea-language-spec/test-cases/09-list-manipulation/01-car.scm +7 -0
- data/flea-language-spec/test-cases/09-list-manipulation/02-cdr.scm +7 -0
- data/flea-language-spec/test-cases/09-list-manipulation/03-list-tail.scm +7 -0
- data/flea-language-spec/test-cases/09-list-manipulation/04-append.scm +10 -0
- data/flea-language-spec/test-cases/09-list-manipulation/05-list.scm +5 -0
- data/flea-language-spec/test-cases/10-functional-examples/countdown.scm +15 -0
- data/lib/flea.rb +5 -0
- data/lib/flea/environment.rb +38 -0
- data/lib/flea/interpreter.rb +67 -0
- data/lib/flea/standard_library/addition_operator.scm +7 -0
- data/lib/flea/standard_library/append.scm +7 -0
- data/lib/flea/standard_library/begin.scm +11 -0
- data/lib/flea/standard_library/car.scm +7 -0
- data/lib/flea/standard_library/cdr.scm +7 -0
- data/lib/flea/standard_library/cons.scm +13 -0
- data/lib/flea/standard_library/display.scm +8 -0
- data/lib/flea/standard_library/division_operator.scm +7 -0
- data/lib/flea/standard_library/equality_operator.scm +8 -0
- data/lib/flea/standard_library/gets.scm +6 -0
- data/lib/flea/standard_library/greater_than.scm +8 -0
- data/lib/flea/standard_library/if.scm +10 -0
- data/lib/flea/standard_library/lambda.scm +57 -0
- data/lib/flea/standard_library/less_than.scm +8 -0
- data/lib/flea/standard_library/list.scm +8 -0
- data/lib/flea/standard_library/list_predicate.scm +6 -0
- data/lib/flea/standard_library/list_tail.scm +5 -0
- data/lib/flea/standard_library/multiplication_operator.scm +7 -0
- data/lib/flea/standard_library/null.scm +3 -0
- data/lib/flea/standard_library/quote.scm +6 -0
- data/lib/flea/standard_library/rand.scm +6 -0
- data/lib/flea/standard_library/read.scm +6 -0
- data/lib/flea/standard_library/set.scm +9 -0
- data/lib/flea/standard_library/string_to_num.scm +6 -0
- data/lib/flea/standard_library/subtraction_operator.scm +7 -0
- data/spec/flea/environment_spec.rb +114 -0
- data/spec/flea/interpreter_spec.rb +85 -0
- data/spec/flea/standard_library/addition_operator_spec.rb +23 -0
- data/spec/flea/standard_library/append_spec.rb +17 -0
- data/spec/flea/standard_library/begin_spec.rb +20 -0
- data/spec/flea/standard_library/car_spec.rb +17 -0
- data/spec/flea/standard_library/cdr_spec.rb +17 -0
- data/spec/flea/standard_library/cons_spec.rb +25 -0
- data/spec/flea/standard_library/display_spec.rb +36 -0
- data/spec/flea/standard_library/division_operator_spec.rb +29 -0
- data/spec/flea/standard_library/equality_operator_spec.rb +45 -0
- data/spec/flea/standard_library/gets_spec.rb +23 -0
- data/spec/flea/standard_library/greater_than_spec.rb +29 -0
- data/spec/flea/standard_library/if_spec.rb +59 -0
- data/spec/flea/standard_library/lambda_spec.rb +70 -0
- data/spec/flea/standard_library/less_than_spec.rb +29 -0
- data/spec/flea/standard_library/list_predicate_spec.rb +25 -0
- data/spec/flea/standard_library/list_spec.rb +24 -0
- data/spec/flea/standard_library/list_tail_spec.rb +17 -0
- data/spec/flea/standard_library/mutiplication_operator_spec.rb +23 -0
- data/spec/flea/standard_library/null_spec.rb +26 -0
- data/spec/flea/standard_library/quote_spec.rb +20 -0
- data/spec/flea/standard_library/rand_spec.rb +25 -0
- data/spec/flea/standard_library/read_spec.rb +23 -0
- data/spec/flea/standard_library/set_spec.rb +23 -0
- data/spec/flea/standard_library/string_to_num_spec.rb +28 -0
- data/spec/flea/standard_library/subtraction_operator_spec.rb +24 -0
- data/spec/spec_helper.rb +10 -0
- metadata +231 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
(define countdown
|
2
|
+
(lambda (index)
|
3
|
+
(define current (- index 1))
|
4
|
+
(display current)
|
5
|
+
(if (equal? current 1)
|
6
|
+
(display "... Blast off!")
|
7
|
+
(begin
|
8
|
+
(display ", ")
|
9
|
+
(countdown current)))))
|
10
|
+
|
11
|
+
(countdown 11)
|
12
|
+
|
13
|
+
----
|
14
|
+
|
15
|
+
assert_output "10, 9, 8, 7, 6, 5, 4, 3, 2, 1... Blast off!"
|
data/lib/flea.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Flea
|
2
|
+
class Environment
|
3
|
+
|
4
|
+
attr_accessor :parent
|
5
|
+
|
6
|
+
def initialize(parent = nil)
|
7
|
+
@parent = parent
|
8
|
+
@table = {}
|
9
|
+
add_globals if @parent.nil?
|
10
|
+
end
|
11
|
+
|
12
|
+
def has_variable?(name)
|
13
|
+
return true if @table.has_key?(name)
|
14
|
+
return false if @parent.nil?
|
15
|
+
return @parent.has_variable?(name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def find(name)
|
19
|
+
return @table[name] if @table.has_key?(name)
|
20
|
+
return nil if @parent.nil?
|
21
|
+
return @parent.find(name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def define(name, value)
|
25
|
+
@table[name] = value
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def add_globals
|
31
|
+
@table.merge!({
|
32
|
+
:"#t" => true,
|
33
|
+
:"#f" => false
|
34
|
+
})
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Flea
|
2
|
+
class Interpreter
|
3
|
+
|
4
|
+
attr_accessor :base_environment,
|
5
|
+
:current_environment,
|
6
|
+
:parser
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
options = {
|
10
|
+
:base_environment => Environment.new,
|
11
|
+
:load_standard_library => true
|
12
|
+
}.merge(options)
|
13
|
+
|
14
|
+
@base_environment = @current_environment = options[:base_environment]
|
15
|
+
@parser = Sexpistol.new
|
16
|
+
@parser.ruby_keyword_literals = false
|
17
|
+
@parser.scheme_compatability = true
|
18
|
+
|
19
|
+
load_standard_library unless options[:load_standard_library] == false
|
20
|
+
end
|
21
|
+
|
22
|
+
def run(program)
|
23
|
+
expressions = parse(program)
|
24
|
+
result = nil
|
25
|
+
expressions.each do |expression|
|
26
|
+
result = evaluate(expression)
|
27
|
+
end
|
28
|
+
|
29
|
+
return result
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse(string)
|
33
|
+
return @parser.parse_string(string)
|
34
|
+
end
|
35
|
+
|
36
|
+
def evaluate(expression)
|
37
|
+
return @current_environment.find(expression) if expression.is_a? Symbol
|
38
|
+
return expression unless expression.is_a? Array
|
39
|
+
|
40
|
+
if expression[0] == :define
|
41
|
+
return @current_environment.define expression[1], evaluate(expression[2])
|
42
|
+
|
43
|
+
elsif expression[0] == :native_function
|
44
|
+
return eval expression[1]
|
45
|
+
|
46
|
+
else # function call
|
47
|
+
function = evaluate(expression[0])
|
48
|
+
raise RuntimeError, "\n#{@parser.to_sexp(expression)}\n ^\n\n#{expression[0]} is not a function" unless function.is_a? Proc
|
49
|
+
arguments = expression.slice(1, expression.length)
|
50
|
+
return function.call(arguments, self)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def load_standard_library
|
57
|
+
library_pattern = File.join(File.dirname(__FILE__), 'standard_library', '*.scm')
|
58
|
+
|
59
|
+
Dir[library_pattern].each do |item|
|
60
|
+
File.open(item) do |file|
|
61
|
+
run(file.read)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|