Class: Lox

Inherits:
Object
  • Object
show all
Extended by:
Dry::Configurable
Defined in:
lib/loxby/core.rb,
lib/loxby/config.rb,
lib/loxby/parser.rb,
lib/loxby/runner.rb,
lib/loxby/scanner.rb,
lib/loxby/version.rb,
lib/loxby/helpers/ast.rb,
lib/loxby/helpers/errors.rb,
lib/loxby/helpers/callable.rb,
lib/loxby/helpers/functions.rb,
lib/loxby/helpers/token_type.rb,
lib/loxby/helpers/environment.rb

Overview

rubocop:disable Style/Documentation

Defined Under Namespace

Modules: AST, Callable Classes: DividedByZeroError, Environment, Function, ParseError, Parser, RunError, Runner, Scanner, Token

Constant Summary collapse

VERSION =
'0.0.3'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeLox

Returns a new instance of Lox.



16
17
18
19
20
21
22
23
# File 'lib/loxby/core.rb', line 16

def initialize
  # Whether an error occurred while parsing.
  @errored = false
  # Whether an error occurred while interpreting
  @errored_in_runtime = false
  # `Lox::Interpreter` instance. Static so interactive sessions reuse it
  @interpreter = Interpreter.new(self)
end

Instance Attribute Details

#erroredObject (readonly)

Returns the value of attribute errored.



14
15
16
# File 'lib/loxby/core.rb', line 14

def errored
  @errored
end

#interpreterObject (readonly)

Returns the value of attribute interpreter.



14
15
16
# File 'lib/loxby/core.rb', line 14

def interpreter
  @interpreter
end

Instance Method Details

#error(line, message) ⇒ Object



65
66
67
68
69
70
71
72
73
74
# File 'lib/loxby/core.rb', line 65

def error(line, message)
  if line.is_a? Lox::Token
    # Parse/runtime error
    where = line.type == :eof ? 'end' : "'#{line.lexeme}'"
    report(line.line, " at #{where}", message)
  else
    # Scan error
    report(line, '', message)
  end
end

#run(source) ⇒ Object

Parse and run a string



56
57
58
59
60
61
62
63
# File 'lib/loxby/core.rb', line 56

def run(source)
  tokens = Scanner.new(source, self).scan_tokens
  parser = Parser.new(tokens, self)
  statements = parser.parse
  return if @errored

  @interpreter.interpret statements
end

#run_file(path) ⇒ Object

Parse and run a file



26
27
28
29
30
31
32
33
34
35
36
# File 'lib/loxby/core.rb', line 26

def run_file(path)
  if File.exist? path
    catch(:lox_exit) do
      run File.read(path)
    end
  else
    report(0, '', "No such file: '#{path}'")
  end
  exit Lox.config.exit_code.syntax_error if @errored # Don't execute malformed code
  exit Lox.config.exit_code.runtime_error if @errored_in_runtime
end

#run_promptObject

Run interactively, REPL-style



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/loxby/core.rb', line 39

def run_prompt
  catch(:lox_exit) do
    loop do
      print '> '
      line = gets
      break unless line # Trap eof (Ctrl+D unix, Ctrl+Z win)

      result = run(line)
      puts "=> #{@interpreter.lox_obj_to_str result}" unless @errored

      # When run interactively, resets after every prompt so as to not kill the repl
      @errored = false
    end
  end
end

#runtime_error(err) ⇒ Object

rubocop:disable Style/StderrPuts



78
79
80
81
82
# File 'lib/loxby/core.rb', line 78

def runtime_error(err)
  $stderr.puts err.message
  $stderr.puts "[line #{err.token.line}]"
  @errored_in_runtime = true
end