Module: Hivemind
- Defined in:
- lib/hivemind/vm.rb,
lib/hivemind/errors.rb,
lib/hivemind/syntax.rb,
lib/hivemind/runtime.rb,
lib/hivemind/renderer.rb,
lib/hivemind/environment.rb,
lib/hivemind/universal_ast.rb
Defined Under Namespace
Modules: Runtime, UniversalAST Classes: Environment, HivemindAccessError, HivemindMissingNameError, Renderer, Syntax, VM
Constant Summary collapse
- TYPES =
{ assign: { left: :name, right: :expr }, attribute: { object: :expr_no_attr, label: :name_or_attr }, image: { statements: :class_statement }, binary: { left: :expr_no_binary, operation: :operation, right: :expr }, attribute_assign: { object: :expr_no_attr, label: :name_or_attr, right: :expr }, call: { function: :expr_no_call, args: :expr }, list: { elements: :expr }, dictionary: { pair: :pair }, pair: { key: :string, value: :expr }, method_statement: { method_name: :name, args: :name, body: :expr }, class_statement: { class_name: :name, methods: :method_statement }, module_statement: { module_name: :name, elements: :statement }, if_statement: { test: :expr, true_branch: :expr, else_branch: :expr } }
- Name =
UniversalAST::Name
- Number =
UniversalAST::Number
- Assign =
UniversalAST::Assign
- Element =
UniversalAST::Element
- Call =
UniversalAST::Call
- List =
UniversalAST::List
- Dictionary =
UniversalAST::Dictionary
- Pair =
UniversalAST::Pair
- Attribute =
UniversalAST::Attribute
- AttributeAssign =
UniversalAST::AttributeAssign
- IfStatement =
UniversalAST::IfStatement
- MethodStatement =
UniversalAST::MethodStatement
- ClassStatement =
UniversalAST::ClassStatement
- Image =
UniversalAST::Image
- Operation =
UniversalAST::Operation
- Float =
UniversalAST::Float
- Int =
UniversalAST::Int
- REFS =
{ name: Apply.new(Mat.new(/[a-zA-Z][a-zA-Z_]*/)) do |result| Name.new(result.to_sym) end, image: Apply.new(Join.new(Ref.new(:class_statement), "", as: :statements)) do |children| # d = children.select { |child| child.is_a?(MethodStatement) } e = children.select { |child| child.is_a?(ClassStatement) } # obj = e.find { |element| element.is_a?(ClassStatement) && element.class_name == :Object } # p e[0].class_name # if obj.nil? && !d.empty? # obj = ClassStatement.new(Name.new(:Object), d) # e << obj # elsif obj # obj.methods += d # end Image.new(e) end, statement: Ref.new(:module_statement) | Ref.new(:class_statement) | Ref.new(:method_statement), number: Ref.new(:float) | Ref.new(:int), float: Apply.new(Mat.new(/[0-9]+\.[0-9]+/)) do |result| Float.new(result.to_f) end, int: Apply.new(Mat.new(/[0-9]+/)) do |result| Int.new(result.to_i) end, string: Apply.new(Mat.new(/\"[^\"]*\"/)) do |result| String.new(result[1..-2]) end, ws: Mat.new(/ +/), nl: Mat.new(/\n*/), indent: Lit.new(''), dedent: Lit.new(''), expr: Ref.new(:attribute_assign) | Ref.new(:assign) | Ref.new(:binary) | Ref.new(:call) | Ref.new(:attribute) | Ref.new(:number) | Ref.new(:name) | Ref.new(:string), expr_no_attr: Ref.new(:number) | Ref.new(:nil) | Ref.new(:name) | Ref.new(:string), expr_no_call: Ref.new(:binary) | Ref.new(:attribute) | Ref.new(:number) | Ref.new(:name) | Ref.new(:string), nil: Lit.new('nil'), name_or_attr: Ref.new(:name) | Ref.new(:attribute), assign: Apply.new(Ref.new(:_assign)) do |results| Assign.new(*results.select { |r| r.is_a?(Element) }) end, attribute_assign: Apply.new(Ref.new(:_attribute_assign)) do |results| AttributeAssign.new(*results.select { |r| r.is_a?(Element) }) end, call: Apply.new(Ref.new(:_call)) do |results| function, args = results.select { |r| r.is_a?(Element) || r.is_a?(Array) } Call.new(function, args) end, list: Apply.new(Ref.new(:_list)) do |results| List.new(results[1]) end, dictionary: Apply.new(Ref.new(:_dictionary)) do |results| Dictionary.new(results[1]) end, pair: Apply.new(Ref.new(:_pair)) do |results| key, value = results.select { |r| r.is_a?(Element) } Pair.new(key, value) end, binary: Apply.new(Ref.new(:_binary)) do |results| if results[0].is_a?(String) results = results[1..-1] end # detect operation intelligently tokens = results[0], results[2], results[4] if tokens[0].is_a?(UniversalAST::Operation) operation, left, right = tokens elsif tokens[1].is_a?(UniversalAST::Operation) left, operation, right = tokens else left, right, operation = tokens end # p results UniversalAST::Binary.new(left, operation, right) end, expr_no_binary: Ref.new(:attribute) | Ref.new(:number) | Ref.new(:name) | Ref.new(:string), operation: Apply.new(Lit.new('+') | Lit.new('-') | Lit.new('**') | Lit.new('/') | Lit.new('*') | Lit.new('||')) do |result| Operation.new(result) end, attribute: Apply.new(Ref.new(:_attribute)) do |results| object, label = results.select { |r| r.is_a?(Element) } Attribute.new(object, label) end, if_statement: Apply.new(Ref.new(:_if_statement)) do |results| test, true_branch, else_branch = results.select { |r| r.is_a?(Element) || r.is_a?(Array) } IfStatement.new(test, true_branch, else_branch) end, method_statement: Apply.new(Ref.new(:_method_statement)) do |results| method_name, args, body = results.select { |r| r.is_a?(Element) || r.is_a?(Array) } MethodStatement.new(method_name, args, body) end, class_statement: Apply.new(Ref.new(:_class_statement)) do |results| class_name, methods = results.select { |r| r.is_a?(Element) || r.is_a?(Array) } ClassStatement.new(class_name, methods) end, module_statement: Apply.new(Ref.new(:_module_statement)) do |results| module_name, classes = results.select { |r| r.is_a?(Element) || r.is_a?(Array) } ModuleStatement.new(module_name, classes) end }
- BASE_RULES =
{ image: -> element, depth = 0 do element.statements.map { |s| render_element(s) }.join("\n") end, int: -> element, depth = 0 do element.value.to_s end, float: -> element, depth = 0 do element.value.to_s end, string: -> element, depth = 0 do '"' + element.value.to_s + '"' end, name: -> element, depth = 0 do element.value.to_s end, operation: -> element, depth = 0 do element.value.to_s end }