Skip to content

alexkowalenko/alox

Repository files navigation

ALOX

ALOX - A Lox implementation in Typescript. Following (not exactly) the book Crafting Interpreters by Robert Nystrom.

Run the REPL by invoking alox.ts.

Progress

  • Lexer - Chapter 4: Scanning.
  • AST - Chapter 5: Representing Code.
  • A REPL.
  • Parser - Expressions - Chapter 6: Parsing Expressions. Implemented using Prat Operator precedence parser (§17.6).
  • Interpreter - Chapter 7: Evaluating Expressions.
  • Assignment, Program structure - Chapter 8: State and Statements
    • Program structure, print.
    • Variables, environment, assignment.
    • Blocks (§8.5 Scope)
  • Test Structure for running test programs.
  • Control flow - Chapter 9.
    • if statements, logical operators partial evaluation
    • while statement.
    • for statement.
    • break and continue.
  • Functions - Chapter 10.
    • Function calls - parsing
    • Native Functions
    • Function declarations
    • return statement.
    • Simple lexical closures
    • Lambda expressions fun(){}
  • Full closures - Chapter 11 - Resolution and Binding
  • Classes - Chapter 12.
    • Definitions class
    • Creation
    • Properties
    • Methods
    • this
    • Constructors
  • Inheritance - Chapter 13.
    • Super classes
    • Inheriting methods
    • Calling superclass methods
  • Extras
    • getc(), chr(), ord().

Part II Bytecode compiler

  • Chunk - Chapter 14 - Bytecode.
  • VM - Chapter 15 - Virtual Machine.
    • Structure for VM.
    • Stack
    • Arithmetic operators.
  • Lexical Scanner - Chapter 16 = Reuse lexer, parser, and analyser.
  • Compiling expressions - Chapter 17.
    • Emitting Bytecode and running bytecode..
  • Runtime type checking - Chapter 18 Types of Values.
    • Arithmetic operations.
    • Relational and Not operations.
  • Strings - Chapter 19.
  • Hash Tables - Chapter 20. Implemented in TypeScript/JavaScript.
  • Global Variables - Chapter 21.
    • print & POP
    • Define global variables
    • Access global variables
  • Test structure for running files with bytecode engine.
  • Local Variables - Chapter 22.
    • Block scopes
    • Define local variables
    • Access local variables
    • Set local variables
  • Control Statements - Chapter 23.
    • if statement.
    • logical operators and, or.
    • while statement.
    • for statement.
    • continue and break.
  • Functions - Chapter 24.
    • Function context for compiler, frames for the vm.
    • Call functions with no arguments.
    • Argument passing.
    • Lambda expressions.
    • Native Functions.
  • Closures - Chapter 25.
    • Wrap functions in closure structure.
    • Upvalues
    • Closed upvalues
  • Garbage Collection - Chapter 26. Implemented in TypeScript/JavaScript.
  • Classes and Instances - Chapter 27.
    • Class objects
    • Instances
  • Methods and Initializers - Chapter 28.
    • Methods.
    • this
    • Constructors.
  • Superclasses - Chapters 29.
    • Inheritance.
    • super.

Problems

  • Differing from the book, every statement returns a value. This led to some messy code to keep stack hygiene in block statements, and also returning from constructors. This was done so that the compiler could be tested via what it returned. If I re-write this interpreter/compiler, I will eliminate this feature and keep it closer to book.

  • TypeScript/JavaScript does not really allow to point to values into the stack, like the C version did. I could have worked it out via a index into the array of the stack, but it is too messy. Thus closures don't work.

  • Line numbers are transferred to the VM via special Opcode LINE - I think this does slow down significantly the VM, as you can't really turn of line numbers due to error code reporting. Line number information should be kept separately in the bytecode chunk, but not fed through the VM.