Skip to content

Commit

Permalink
Changed method definition/block syntax
Browse files Browse the repository at this point in the history
Blocks are now created using "do" and methods using "def". This makes
more sense than using "fn" since "fn" implies it's a regular function
that's being created.
  • Loading branch information
Yorick Peterse committed Oct 15, 2017
1 parent d187df2 commit 0487553
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 43 deletions.
3 changes: 2 additions & 1 deletion compiler/lib/inkoc/lexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ class Lexer
'import' => :import,
'return' => :return,
'self' => :self,
'fn' => :function,
'def' => :define,
'do' => :do,
'throw' => :throw,
'else' => :else,
'try' => :try,
Expand Down
32 changes: 5 additions & 27 deletions compiler/lib/inkoc/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ class Parser
constant
curly_open
float
function
define
do
hash_open
identifier
impl
Expand All @@ -70,8 +71,6 @@ class Parser
]
).freeze

CLOSURE_START = Set.new(%i[paren_open curly_open arrow throws]).freeze

BINARY_OPERATORS = Set.new(
%i[
or
Expand Down Expand Up @@ -456,7 +455,7 @@ def send_argument(start)
case start.type
when :curly_open
block_without_arguments(start)
when :function
when :do
block(start)
else
expression(start)
Expand All @@ -477,7 +476,8 @@ def value(start)
when :sub then negative_number(start)
when :bracket_open then array(start)
when :hash_open then hash(start)
when :function then method_or_block(start)
when :define then def_method(start)
when :do then block(start)
when :let then let_define(start)
when :var then var_define(start)
when :return then return_value(start)
Expand Down Expand Up @@ -668,28 +668,6 @@ def hash(start)
AST::Send.new('from_array', receiver, [keys_array, vals_array], location)
end

# Parses a method or an anonymous block.
#
# Examples:
#
# fn foo { ... }
# fn { ... }
def method_or_block(start)
if @lexer.peek.nil?
raise(
ParseError,
'The "fn" keyword must be followed by a name, ' \
'arguments list or return type'
)
end

if CLOSURE_START.include?(@lexer.peek.type)
block(start)
else
def_method(start)
end
end

# Parses a method definition.
#
# Examples:
Expand Down
2 changes: 1 addition & 1 deletion compiler/lib/inkoc/pass/define_types.rb
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ def infer_and_validate_throw_type(throw_type, scope, location)
block_throws = scope.block_type.throws
scope.block_type.contains_throw = true

if module_scope?(scope.block_type)
if scope.block_type == @module.body.type
diagnostics.throw_at_top_level_error(throw_type, location)
return
end
Expand Down
18 changes: 8 additions & 10 deletions compiler/lib/inkoc/pass/generate_tir.rb
Original file line number Diff line number Diff line change
Expand Up @@ -534,19 +534,17 @@ def on_throw(node, body)
end

def on_try(node, body)
return
# TODO: don't do anything unless an "else" body is provided
return unless node.else_body

# note down start index

registers = process_nodes(node.expressions, body)

# note down end index

body.instruct(:GotoNextBlock, node.location)
# Block for running the to-try expression
body.add_connected_basic_block
process_nodes(node.expressions, body)
body.instruct(:SkipNextBlock, node.location)

# TODO: inject else code here
# Block for error handling
process_nodes(node.else_body.expressions, body)

# Block for everything that comes after our "try" expression.
body.add_connected_basic_block
end

Expand Down
40 changes: 36 additions & 4 deletions runtime/std/bootstrap.inko
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,46 @@
# are defined directly on the top-level object.
![define_module: false]

# Object will act as the prototype for all other objects.
var Object = _INKOC.set_object(_INKOC.get_true)
var True = _INKOC.get_true
var False = _INKOC.get_false

# Object will act as the prototype for all objects.
#
# We need to define Object here instead of in a separate module as all other
# objects depend on it being present.
object Object {
def new -> Self {
let obj = _INKOC.set_object(False, self)

obj.init

obj
}

def init {}

def object_name {
@object_name
}

def implement_trait(thing) {}
}

object Trait {
def init {
# let @required_methods = []
# let @required_traits = []
}

def define_required_method(name) {}
def add_required_trait(thing) {}
}

# Inko::Modules contains all of the imported modules mapped to their fully
# qualified module names.
var Modules = _INKOC.set_object(_INKOC.get_true, Object)
object Modules {}

# Inkoc::Module will act as the prototype for all modules. We'll later refine
# this object in the std::module module, but we need it here to allow us to
# define new modules in the first place.
var Module = _INKOC.set_object(_INKOC.get_true, Object)
object Module {}

0 comments on commit 0487553

Please sign in to comment.