# c-repl -- a C read-eval-print loop.
# Copyright (C) 2006 Evan Martin <martine@danga.com>

# This class parses snippets of code and gives you back an object
# that holds the:
# - declaration (goes at the top level the of the file; can be used with extern)
# - statement (the code that is run, if any)
# - function (which also goes at the top level, but can't be used with extern)
#
# Currently, it doesn't actually do real parsing.
class CodeSnippet
  attr_reader :decl, :stmt, :func
  def initialize(code=nil)
    parse code if code
  end

  def self.with_semi(text)
    return text if text =~ /;$/
    text + ';'
  end

  def parse(code)
    # Some patterns we'd like to support:
    # int x
    # int x = 3
    # void f() { }
    # while() { ... }
    # x = 4

    # Heuristics:
    #  1. first two tokens are non-punct means decl
    #     1. anything after = or { is stmt
    #     2. = means variable declaration
    #     3. { means function declaration
    #  2. everything else is a stmt.

    if code =~ /^\w+\s+\w/   # rule 1
      pos = code =~ /\s*([={])/  # find first of the rule 1.1
      unless pos
        @decl = CodeSnippet.with_semi(code)
      else
        @decl = CodeSnippet.with_semi(code[0,pos])
        case $1
        when '='  # rule 1.2
          code =~ /(\w+\s*=.*)/
          @stmt = CodeSnippet.with_semi($1)
        when '{'  # rule 1.3
          @func = code
        end
      end
    else  # rule 2
      @stmt = CodeSnippet.with_semi(code)
    end
  end

  def self.parse(code)
    self.new(code)
  end
end

# vim: set ts=2 sw=2 et :
