12.2
change ykrzkxlzrvkvsvpozssusqxmlrttxykp
commit 341fa5e9200acdda3c2d51215b31e1aa71876b9b
author Alpha Chen <alpha@kejadlen.dev>
date
parent trtkwwxs
diff --git a/ruby/lib/lox/ast_printer.rb b/ruby/lib/lox/ast_printer.rb
index 6fb8f45..8a89523 100644
--- a/ruby/lib/lox/ast_printer.rb
+++ b/ruby/lib/lox/ast_printer.rb
@@ -49,6 +49,14 @@ module Lox
       parenthesize("while", stmt.cond, stmt.body)
     end
 
+    def visit_class(stmt)
+      parenthesize("class #{stmt.name.lexeme}", *stmt.methods)
+    end
+
+    def visit_function(stmt)
+      parenthesize("function #{stmt.name.lexeme}", *stmt.body)
+    end
+
     private
 
     def parenthesize(name, *exprs)
diff --git a/ruby/lib/lox/lox_class.rb b/ruby/lib/lox/lox_class.rb
new file mode 100644
index 0000000..170fa36
--- /dev/null
+++ b/ruby/lib/lox/lox_class.rb
@@ -0,0 +1,19 @@
+require_relative "instance"
+
+module Lox
+  class LoxClass
+
+    attr_reader :name
+
+    def initialize(name)
+      @name = name
+    end
+
+    def to_s = name
+
+    def call(interpreter, args) = Instance.new(self)
+
+    def arity = 0
+
+  end
+end
diff --git a/ruby/lib/lox/parser.rb b/ruby/lib/lox/parser.rb
index 2c1ecf8..f087ec4 100644
--- a/ruby/lib/lox/parser.rb
+++ b/ruby/lib/lox/parser.rb
@@ -23,12 +23,27 @@ module Lox
     private
 
     def declaration
+      return class_decl if match?(:CLASS)
       return function("function") if match?(:FUN)
       return var_declaration if match?(:VAR)
 
       statement
     end
 
+    def class_decl
+      name = consume!(:IDENTIFIER, "Expect class name.")
+      consume!(:LEFT_BRACE, "Expect '{' before class body.")
+
+      methods = []
+      until check?(:RIGHT_BRACE) || eot?
+        methods << function("method")
+      end
+
+      consume!(:RIGHT_BRACE, "Expect '}' after class body.")
+
+      Stmt::Class.new(name, methods)
+    end
+
     def var_declaration
       name = consume!(:IDENTIFIER, "Expect variable name.")
       initializer = match?(:EQUAL) ? expression : nil
diff --git a/ruby/lib/lox/stmt.rb b/ruby/lib/lox/stmt.rb
index e4bfc54..23d31a6 100644
--- a/ruby/lib/lox/stmt.rb
+++ b/ruby/lib/lox/stmt.rb
@@ -13,8 +13,9 @@ module Lox
     end
 
     stmt :Block, :stmts
-    stmt :Function, :name, :params, :body
+    stmt :Class, :name, :methods
     stmt :Expr, :expr
+    stmt :Function, :name, :params, :body
     stmt :If, :cond, :then, :else
     stmt :Print, :expr
     stmt :Return, :keyword, :value
diff --git a/ruby/test/lox/test_parser.rb b/ruby/test/lox/test_parser.rb
index 0e73a26..8b02820 100644
--- a/ruby/test/lox/test_parser.rb
+++ b/ruby/test/lox/test_parser.rb
@@ -96,6 +96,22 @@ class TestParser < Lox::Test
     AST
   end
 
+  def test_class
+    assert_parsed <<~AST.chomp, :declaration, <<~SRC
+      (class Breakfast (function cook (print Eggs a-fryin'!)) (function serve (print (+ (+ Enjoy your breakfast,  (var who)) .))))
+    AST
+      class Breakfast {
+        cook() {
+          print "Eggs a-fryin'!";
+        }
+
+        serve(who) {
+          print "Enjoy your breakfast, " + who + ".";
+        }
+      }
+    SRC
+  end
+
   private
 
   def assert_parsed(expected, name, src)