Skip to content

Commit

Permalink
Merge branch 'flexible_conditionals'
Browse files Browse the repository at this point in the history
Conflicts:
	lib/object.fy
  • Loading branch information
bakkdoor committed Apr 28, 2011
2 parents 82d45dd + 18dbea2 commit a1250ad
Show file tree
Hide file tree
Showing 27 changed files with 368 additions and 135 deletions.
6 changes: 3 additions & 3 deletions bin/ifancy
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ load_history
try {
bnd = binding()

{ Readline readline(">> ", true) } while_do: |line| {
while: { Readline readline(">> ", true) } do: |line| {
HISTORY << line
double_or_empty?: line . if_true: {
if: (double_or_empty?: line) then: {
Readline::HISTORY pop()
HISTORY pop()
}

line =~ /^\s*$/ if_false: {
unless: (line =~ /^\s*$/) do: {
try {
Fancy eval: line binding: bnd . inspect println
} catch Exception => e {
Expand Down
2 changes: 1 addition & 1 deletion examples/echo.fy
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# echo.fy
# Outputs contents of files

ARGV[1] if_do: |filename| {
ARGV[1] if_true: |filename| {
try {
File open: filename modes: ['read] with: |f| {
until: { f eof? } do: {
Expand Down
4 changes: 2 additions & 2 deletions examples/game_of_life.fy
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class World {
def was_alive?: pos {
"Indicates, if a cell ([row,column]) was alive in the last generation."

@last_alive[pos[0]] if_do: |row| {
@last_alive[pos[0]] if_true: |row| {
row[pos[1]] == 1
}
}
Expand Down Expand Up @@ -115,7 +115,7 @@ class World {
column = pos[1]

neighbors = @offsets map: |o| {
@matrix[row + (o[0])] if_do: |r| {
@matrix[row + (o[0])] if_true: |r| {
r[column + (o[1])]
}
}
Expand Down
4 changes: 2 additions & 2 deletions lib/argv.fy
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
def ARGV for_option: op_name do: block {
"Runs a given block if an option is in ARGV."

ARGV index: op_name . if_do: |idx| {
ARGV index: op_name . if_true: |idx| {
if: (block argcount > 0) then: {
ARGV[idx + 1] if_do: |arg| {
ARGV[idx + 1] if_true: |arg| {
block call: [arg]
ARGV remove_at: idx
ARGV remove_at: idx
Expand Down
2 changes: 1 addition & 1 deletion lib/block.fy
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class Block {

def while_true: work {
{
call if_do: |val| {
call if_true: |val| {
work call: [val]
} else: {
break
Expand Down
3 changes: 2 additions & 1 deletion lib/boot.fy
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ require: "array"
require: "tuple"
require: "block"
require: "iteration"
require: "enumerator"
require: "file"
require: "directory"
require: "fancy_spec"
Expand All @@ -46,4 +47,4 @@ require: "argv"

require: "documentation"

require: "package.fy"
require: "package.fy"
2 changes: 1 addition & 1 deletion lib/compiler/ast/class_def.fy
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Fancy AST {
def bytecode: g {
pos(g)
docstring = body() body() shift_docstring
docstring if_do: {
docstring if_true: {
setdoc = MessageSend new: @line \
message: (Identifier from: "for:append:" line: @line) \
to: (Identifier from: "Fancy::Documentation" line: @line) \
Expand Down
4 changes: 2 additions & 2 deletions lib/compiler/ast/identifier.fy
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ class Fancy AST {
}

def method_name: receiver ruby_send: ruby (false) {
ruby || @ruby_ident if_do: {
ruby || @ruby_ident if_true: {
@string to_sym()
} else: {
@string =~ /:$/ . if_do: {
@string =~ /:$/ . if_true: {
@string to_sym()
} else: {
":" + @string . to_sym()
Expand Down
4 changes: 2 additions & 2 deletions lib/compiler/ast/method_def.fy
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ class Fancy AST {
g send(@access, 0)
g pop()

@name to_s =~ /^initialize:(\S)+/ if_do: {
@name to_s =~ /^initialize:(\S)+/ if_true: {
define_constructor_class_method: g
}
@name to_s =~ /^unknown_message:with_params:$/ if_do: {
@name to_s =~ /^unknown_message:with_params:$/ if_true: {
define_method_missing: g
}

Expand Down
2 changes: 1 addition & 1 deletion lib/documentation.fy
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class Fancy Documentation {
If obj has no documentation, one is created for it.
"""
doc = for: obj
doc if_do: {
if: doc then: {
doc docs << docstring
} else: {
doc = for: obj is: docstring
Expand Down
2 changes: 1 addition & 1 deletion lib/enumerable.fy
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class FancyEnumerable {
"""

each: |x| {
block call: [x] . if_do: |item| {
if: (block call: [x]) then: |item| {
return item
}
}
Expand Down
77 changes: 77 additions & 0 deletions lib/enumerator.fy
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
class FancyEnumerator {
def initialize: @object {
@iterator = 'each:
rewind
}

def initialize: @object with: @iterator {
rewind
}

def next {
if: @peeked then: {
@peeked = false
@peek
} else: {
result = @fiber resume
if: (@fiber alive?) then: {
return result
} else: {
(Fancy StopIteration new: result) raise!
}
}
}

def peek {
"""
Returns the next object in the FancyEnumerator, but doesn't move the
internal position forward.
When the position reaches the end, a Fancy StopIteration exception is
raised.
a = [1,2,3]
e = a to_enum
e next p #=> 1
e peek p #=> 2
e peek p #=> 2
e peek p #=> 2
e next p #=> 2
e next p #=> 3
e next p #=> raises Fancy StopIteration
"""

unless: @peeked do: {
@peeked = true
@peek = @fiber resume
if: (@fiber alive?) then: {
return @peek
} else: {
(Fancy StopIteration new: result) raise!
}
}

return @peek
}

def rewind {
@peeked = false
@peek = nil

@fiber = Fiber new: {
param = |element| { yield: element }
@object send_message: @iterator with_params: [param]
}
}

def with: object each: block {
loop: {
try {
block call: [next, object]
} catch (Fancy StopIteration) => ex {
return object
}
}

return object
}
}
28 changes: 11 additions & 17 deletions lib/false_class.fy
Original file line number Diff line number Diff line change
@@ -1,41 +1,35 @@
class FalseClass {
"FalseClass. The class of the singleton @false value."

def if_true: then_block else: else_block {
"Calls @else_block."
else_block call
def FalseClass new {
# always return false singleton object when trying to create a new
# FalseClass instance
false
}

def if_true: block {
"Returns @nil."
nil
}

def if_false: block {
"Calls @block."
block call
def if_true: then_block else: else_block {
"Calls @else_block."
else_block call
}

def if_nil: block {
"Calls @block."
nil
def if_false: block {
block call: [self]
}

def nil? {
"Returns @false."
false
def if_false: then_block else: else_block {
then_block call: [self]
}

def false? {
"Returns @true."
true
}

def true? {
"Returns @false."
false
}

def to_s {
"Returns @false as a @String@."
"false"
Expand Down
2 changes: 1 addition & 1 deletion lib/fancy_spec.fy
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class FancySpec {
def it: spec_info_string for: method_name when: spec_block {
test = SpecTest new: spec_info_string block: spec_block
# try {
# @test_obj method: method_name . if_do: |method| {
# @test_obj method: method_name . if_true: |method| {
# method tests << test
# }
# } catch MethodNotFoundError => e {
Expand Down
4 changes: 2 additions & 2 deletions lib/fdoc.fy
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,8 @@ class Fancy FDoc {
method = method sub(/^:/, "")
}
sigil = ""
name =~ (Regexp.new("^#")) . if_do: { sigil = "<small>#</small>" }
type = n[1] include?(":") . if_do: {
name =~ (Regexp.new("^#")) . if_true: { sigil = "<small>#</small>" }
type = n[1] include?(":") . if_true: {
if: (sigil == "") then: {
"singleton-method-ref"
} else: {
Expand Down
49 changes: 49 additions & 0 deletions lib/iteration.fy
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,53 @@ class Fancy {
read_slots: ['return_value]
def initialize: @return_value {}
}

class StopIteration : StdError {
"""
Raised to stop the iteration, in particular by Enumerator#next.
It is rescued by Block#loop.
Example:
{
'Hello println
StopIteration new raise!
'World println
} loop
'Done! println
Produces:
Hello
Done!
"""

def initialize { @result = nil }
def initialize: @result { }

def result {
"""
Returns the return value of the iterator.
o = Object new
def o each: block {
block call: 1
block call: 2
block call: 3
100
}
e = o to_enum
e next p #=> 1
e next p #=> 2
e next p #=> 3
try {
e next
} catch Fancy StopIteration => ex {
ex result p #=> 100
}
"""

@result
}
}
}
8 changes: 4 additions & 4 deletions lib/main.fy
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ ARGV for_option: "-e" do: |eval_string| {
}

ARGV for_option: "-c" do: {
ARGV index: "-c" . if_do: |idx| {
ARGV index: "-c" . if_true: |idx| {
ARGV[[idx + 1, -1]] each: |filename| {
"Compiling " ++ filename println
Fancy Compiler compile_file: filename to: nil line: 1 print: false
Expand All @@ -49,7 +49,7 @@ ARGV for_option: "-c" do: {
}

ARGV for_option: "-cv" do: {
ARGV index: "-cv" . if_do: |idx| {
ARGV index: "-cv" . if_true: |idx| {
ARGV[[idx + 1, -1]] each: |filename| {
"Compiling " ++ filename println
Fancy Compiler compile_file: filename to: nil line: 1 print: true
Expand Down Expand Up @@ -77,14 +77,14 @@ ARGV for_option: "list-packages" do: {
Fancy Package add_to_loadpath

# Load a source file, if any given:
ARGV first if_do: |file| {
ARGV first if_true: |file| {
try {
Fancy CodeLoader load_compiled_file: file
} catch Fancy Parser ParseError => e {
e message println
}
}

ARGV empty? if_do: {
ARGV empty? if_true: {
require: "../bin/ifancy"
}
Loading

0 comments on commit a1250ad

Please sign in to comment.