module Apricot

This file contains some things that are used in a bunch of places and don’t fit anywhere in particular.

Constants

Core
LIB_PATH
VERSION

Public Class Methods

compile_error(file, line, msg) click to toggle source
# File lib/apricot/errors.rb, line 35
def self.compile_error(file, line, msg)
  raise CompileError.new(file, line, msg)
end
current_namespace() click to toggle source
# File lib/apricot/namespace.rb, line 68
def current_namespace
  Core.get_var(:"*ns*")
end
current_namespace=(ns) click to toggle source
# File lib/apricot/namespace.rb, line 72
def current_namespace=(ns)
  Core.set_var(:"*ns*", ns)
end
gensym(prefix = 'g') click to toggle source
# File lib/apricot/misc.rb, line 8
def self.gensym(prefix = 'g')
  @gensym += 1
  Identifier.intern("#{prefix}__#{@gensym}")
end
let(g, args, type) click to toggle source

Code shared between let and loop. type is :let or :loop

# File lib/apricot/special_forms.rb, line 24
def self.let(g, args, type)
  g.compile_error "Too few arguments to #{type}" if args.count < 1
  g.compile_error "First argument to #{type} must be an array literal" unless args.first.is_a? Array

  bindings, body = args.first, args.rest

  g.compile_error "Bindings array for #{type} must contain an even number of forms" if bindings.length.odd?

  scope = LetScope.new(g.scope)
  g.scopes << scope

  bindings.each_slice(2) do |id, value|
    g.compile_error "Binding targets in #{type} must be identifiers" unless id.is_a? Identifier

    Compiler.bytecode(g, value)
    g.set_local scope.new_local(id)
    g.pop
  end

  if type == :loop
    scope.loop_label = g.new_label
    scope.loop_label.set!
  end

  SpecialForm[:do].bytecode(g, body)

  g.scopes.pop
end
load(file) click to toggle source
# File lib/apricot/code_loader.rb, line 2
def self.load(file)
  CodeLoader.load(file)
end
macroexpand(form) click to toggle source
# File lib/apricot/macroexpand.rb, line 2
def self.macroexpand(form)
  ex = macroexpand_1(form)

  until ex.equal?(form)
    form = ex
    ex = macroexpand_1(form)
  end

  ex
end
macroexpand_1(form) click to toggle source
# File lib/apricot/macroexpand.rb, line 13
def self.macroexpand_1(form)
  return form unless form.is_a? Seq

  callee = form.first
  return form unless callee.is_a?(Identifier) && !callee.constant?

  name = callee.name
  name_s = name.to_s
  args = form.rest

  # Handle the (.method receiver args*) send expression form
  if name.length > 1 && name != :'..' && name_s.start_with?('.')
    raise ArgumentError, "Too few arguments to send expression, expecting (.method receiver ...)" if args.empty?

    dot = Identifier.intern(:'.')
    method = Identifier.intern(name_s[1..-1])
    return List[dot, args.first, method, *args.rest]
  end

  # Handle the (Class. args*) shorthand new form
  if name.length > 1 && name != :'..' && name_s.end_with?('.')
    dot = Identifier.intern(:'.')
    klass = Identifier.intern(name_s[0..-2])
    new = Identifier.intern(:new)
    return List[dot, klass, new, *args]
  end

  # Handle defined macros
  if callee.qualifier.is_a?(Namespace) && callee.qualifier.vars.include?(callee.unqualified_name)
    potential_macro = callee.qualifier.get_var(callee.unqualified_name)
    meta = potential_macro.apricot_meta

    if meta && meta[:macro]
      return potential_macro.call(*args)
    end
  end

  # Default case
  form
end
require(file) click to toggle source
# File lib/apricot/code_loader.rb, line 6
def self.require(file)
  CodeLoader.require(file)
end