Module: Calcula

Defined in:
lib/Expr.rb,
lib/calcula.rb,
lib/calcula/version.rb

Overview

This module contains the lexer and the parser for Calcula. In the future, the runtime aspect will be included also.

Author:

  • Paul T.

Defined Under Namespace

Modules: Exprs Classes: Expr, Lexer, Parser, Token

Constant Summary collapse

VERSION =
"1.2.0"

Class Method Summary collapse

Class Method Details

.compile(src) ⇒ String

Combines the essential declarations with the compiled Calcula code together

Parameters:

  • src (String)

    The Calcula source code

Returns:

  • (String)

    The complete executable ruby code


83
84
85
86
87
88
89
# File 'lib/calcula.rb', line 83

def Calcula::compile(src)
  <<-EOS
#{Calcula::stdRubyHeader}
# CALCULA SOURCE CODE STARTS HERE
#{Calcula::parse(Calcula::lex(src)).collect{ |e| e.to_s(form: :ruby) }.join("\n")}
  EOS
end

.lex(txt) ⇒ Array<Calcula::Token>

Short hand for calling `Calcula::Lexer.new(txt).lex`

Parameters:

  • txt (String)

    The Calcula source code

Returns:

See Also:


27
28
29
# File 'lib/calcula.rb', line 27

def Calcula::lex(txt)
  Lexer.new(txt).lex
end

.parse(toks) ⇒ Array<Calcula::Expr>

Short hand for calling `Calcula::Parser.new(toks).parse` repetitively.

Parameters:

  • toks (Array<Calcula::Token>)

    This should be supplied by `Calcula::lex`.

Returns:

See Also:


36
37
38
39
40
41
42
43
# File 'lib/calcula.rb', line 36

def Calcula::parse(toks)
  rst = []
  parser = Parser.new(toks)
  while (r = parser.parse) != nil do
    rst << r
  end
  return rst
end

.stdRubyHeaderString

Essential declarations so the Calcula to Ruby option will work

Returns:

  • (String)

    The declarations


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/calcula.rb', line 48

def Calcula::stdRubyHeader
  txt = <<-EOT
class Numeric
def call(x)   # Allowing 10.(20) to work (becomes 200)
  self * x
end
end
class Proc
def +(g)
  ->(*args){ self.(*args) + g.(*args) }
end
def -(g)
  ->(*args){ self.(*args) - g.(*args) }
end
def *(g)
  ->(*args){ self.(*args) * g.(*args) }
end
def /(g)
  ->(*args){ self.(*args) / g.(*args) }
end
def %(g)
  ->(*args){ self.(*args) % g.(*args) }
end
def **(g)
  ->(*args){ self.(*args) ** g.(*args) }
end
end
  EOT
  return txt
end