calcula 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: acb99c969e886a94ca30cc534dc3db8c76f0ea0a
4
- data.tar.gz: f5801be3a546e8aef049aa56cd566dcf53e27d0f
3
+ metadata.gz: 397e946ee023cbfbe15fbd3c78e7fda729e9fa41
4
+ data.tar.gz: ad9f8f5b4da62221b96e08e4ff3afd2887317f40
5
5
  SHA512:
6
- metadata.gz: 6c254c1b82fd8b658e28b876fbaa8c2bde737e57360cc748640cca4253b5d2a451845d1196fc4ee0645cb5769faec78ecb014f7495c90967580fccdc94b60c46
7
- data.tar.gz: 92c14c7803111bde6c62e52b128fccc6bc7f40d175b348f6178a67fd6def282222dea3407416076ad63bbd822255d75450ff7dc6d4d2caae982549a70142eecd
6
+ metadata.gz: 9017478c73db894b546a21bd0563a5e40cbca71281831223fe345b581a0d5c585791195fc1f10c988a413ba81715ddd792967c95882cca31cfe573e573a15817
7
+ data.tar.gz: f4033ce6ce081fbf36995db752a7f90c96844663949d78abdc5fa7846b4cef0e808728940dcce1a4bc1508f996c6fdb6092f7a69b7d08f9ab0136bca527c9778
data/.travis.yml CHANGED
@@ -3,3 +3,6 @@ language: ruby
3
3
  rvm:
4
4
  - 2.3.1
5
5
  before_install: gem install bundler -v 1.13.2
6
+ addons:
7
+ code_climate:
8
+ repo_token: 4ca379840aee24144c568378f1425a8a330e1e1ab46043ffcf16660d0ffa9de2
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in calcula.gemspec
4
4
  gemspec
5
+
6
+ gem "codeclimate-test-reporter", group: :test, require: nil
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2016 TODO: Write your name
3
+ Copyright (c) 2016 Paul T.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Calcula [![Build Status](https://travis-ci.org/plankp/Calcula.svg?branch=master)](https://travis-ci.org/plankp/Calcula) [![Inline docs](http://inch-ci.org/github/plankp/Calcula.svg?branch=master)](http://inch-ci.org/github/plankp/Calcula)
1
+ # Calcula [![Build Status](https://travis-ci.org/plankp/Calcula.svg?branch=master)](https://travis-ci.org/plankp/Calcula) [![Code Climate](https://codeclimate.com/github/plankp/Calcula/badges/gpa.svg)](https://codeclimate.com/github/plankp/Calcula) [![Inline docs](http://inch-ci.org/github/plankp/Calcula.svg?branch=master)](http://inch-ci.org/github/plankp/Calcula) [![Gem Version](https://badge.fury.io/rb/calcula.svg)](https://badge.fury.io/rb/calcula)
2
2
 
3
3
  When mathematics meets programming
4
4
 
@@ -22,17 +22,14 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- At the moment, all it does is converts source code into tokens and then a syntax tree.
26
- To do so, type in:
25
+ To compile Calcula code to ruby, type in:
27
26
 
28
27
  ```ruby
29
28
  require "calcula"
30
29
  src = <<-'EOS'
31
- # Write some calcula code here
30
+ # Write some Calcula code here
32
31
  EOS
33
- tokens = Calcula.lex(src)
34
- puts tokens.collect { |e| e.text }.to_s
35
- puts Calcula.parse(tokens).to_tree
32
+ puts Calcula::compile(src)
36
33
  ```
37
34
 
38
35
  ## Development
@@ -47,4 +44,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/plankp
47
44
 
48
45
  ## License
49
46
 
50
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
47
+ The gem is available as open source under the terms of the [MIT License](./LICENSE.txt).
data/lib/Expr.rb CHANGED
@@ -1,20 +1,40 @@
1
+ # @author Paul T.
1
2
  module Calcula
2
- class Expr
3
-
4
- def to_s()
5
- ""
6
- end
7
3
 
8
- def to_tree()
9
- "()"
10
- end
4
+ # All valid tree expression must be childrens of this class and should be
5
+ # placed under the module `Calcula::Exprs`
6
+ #
7
+ # @see Calcula::Exprs
8
+ # @abstract
9
+ # @author Paul T.
10
+ class Expr
11
11
 
12
- # binding: Hash[string, Any]
13
- def exec(binding)
14
- nil
12
+ # Converts the expression to a string. If the form is `:src`, then the
13
+ # resulting string should resemble as much as its source code as possible.
14
+ # If the form is `:tree`, the result string should resemble in a Lisp like
15
+ # form. If the form is `:ruby`, the result should be Ruby code that does the
16
+ # same thing. Otherwise, `nil` should be returned.
17
+ #
18
+ # @param form [Optional, Symbol] The type of format being converted into
19
+ # @return [String, nil] A string that resembles the specify form
20
+ def to_s(form: :src)
21
+ case form
22
+ when :src then
23
+ ""
24
+ when :tree then
25
+ "()"
26
+ when :ruby then
27
+ ""
28
+ else
29
+ nil
30
+ end
15
31
  end
16
32
 
17
- def children()
33
+ # Returns the child nodes as a list. Child nodes must be transversible
34
+ # (hence also expressions).
35
+ #
36
+ # @return [Array<Calcula::Expr>] A list of transversible child nodes
37
+ def children
18
38
  []
19
39
  end
20
40
  end
@@ -0,0 +1,39 @@
1
+ require_relative "../Expr"
2
+
3
+ # Expression for assigning value to variables
4
+ #
5
+ # @author Paul T.
6
+ class Calcula::Exprs::AssignExpr < Calcula::Expr
7
+
8
+ # @param ident [Calcula::Exprs::IdentExpr]
9
+ # @param value [Calcula::Expr]
10
+ def initialize(ident, value)
11
+ @ident = ident
12
+ @value = value
13
+ end
14
+
15
+ # @see Calcula::Expr#to_s
16
+ # @param (see Calcula::Expr#to_s)
17
+ # @return (see Calcula::Expr#to_s)
18
+ def to_s(form: :src)
19
+ identTxt = @ident.to_s(form: form)
20
+ valueTxt = @value.to_s(form: form)
21
+ case form
22
+ when :src then
23
+ "let #{identTxt}=#{valueTxt}"
24
+ when :tree then
25
+ "(let #{identTxt} #{valueTxt})"
26
+ when :ruby then
27
+ "#{identTxt} = #{valueTxt}"
28
+ else
29
+ nil
30
+ end
31
+ end
32
+
33
+ # @see Calcula::Expr#children
34
+ # @param (see Calcula::Expr#children)
35
+ # @return (see Calcula::Expr#children)
36
+ def children
37
+ [@ident, @value]
38
+ end
39
+ end
@@ -0,0 +1,53 @@
1
+ require_relative "../Expr"
2
+
3
+ # Expression for binary operators. An expression 10(2) is also a binary operator.
4
+ # Its operator will be `:PAREN_O`
5
+ #
6
+ # @author Paul T.
7
+ class Calcula::Exprs::BinopExpr < Calcula::Expr
8
+
9
+ # @param op [Calcula::Token] Should have type prefixed with `OP_`
10
+ # @param left [Calcula::Expr]
11
+ # @param right [Calcula::Expr]
12
+ def initialize(op, left, right)
13
+ @op = op
14
+ @left = left
15
+ @right = right
16
+ end
17
+
18
+ # @see Calcula::Expr#to_s
19
+ # @param (see Calcula::Expr#to_s)
20
+ # @return (see Calcula::Expr#to_s)
21
+ def to_s(form: :src)
22
+ leftTxt = @left.to_s(form: form)
23
+ rightTxt = @right.to_s(form: form)
24
+ case form
25
+ when :src, :ruby then
26
+ case @op.id
27
+ when :PAREN_O then
28
+ "#{leftTxt}#{"." if form == :ruby}(#{rightTxt})"
29
+ when :OP_EQ then
30
+ "#{leftTxt}#{form == :ruby ? "==" : "="}#{rightTxt}"
31
+ when :AND then
32
+ "#{leftTxt}#{form == :ruby ? "&&" : " and "}#{rightTxt}"
33
+ when :OR then
34
+ "#{leftTxt}#{form == :ruby ? "||" : " or "}#{rightTxt}"
35
+ when :COMPOSE then
36
+ "->(*x){#{leftTxt}.(#{rightTxt}.(*x))}"
37
+ else
38
+ "#{leftTxt}#{@op.text}#{rightTxt}"
39
+ end
40
+ when :tree then
41
+ "(#{@op.text} #{leftTxt} #{rightTxt})"
42
+ else
43
+ nil
44
+ end
45
+ end
46
+
47
+ # @see Calcula::Expr#children
48
+ # @param (see Calcula::Expr#children)
49
+ # @return (see Calcula::Expr#children)
50
+ def children
51
+ [@left, @right]
52
+ end
53
+ end
@@ -0,0 +1,48 @@
1
+ require_relative "../Expr"
2
+
3
+ # Expression for bracket operators. Floor operators also count as bracket
4
+ # operators.
5
+ #
6
+ # @author Paul T.
7
+ class Calcula::Exprs::BracedExpr < Calcula::Expr
8
+
9
+ # @param startTok [Calcula::Token] The starting token of this expression
10
+ # @param endTok [Calcula::Token] The ending token of this expression
11
+ # @param inner [Calcula::Expr]
12
+ def initialize(startTok, endTok, inner)
13
+ @startTok = startTok
14
+ @endTok = endTok
15
+ @inner = inner
16
+ end
17
+
18
+ # @see Calcula::Expr#to_s
19
+ # @param (see Calcula::Expr#to_s)
20
+ # @return (see Calcula::Expr#to_s)
21
+ def to_s(form: :src)
22
+ innerTxt = @inner.to_s(form: form)
23
+ case form
24
+ when :src then
25
+ "#{@startTok.text}#{innerTxt}#{@endTok.text}"
26
+ when :tree then
27
+ "#{@startTok.text} #{innerTxt} #{@endTok.text}"
28
+ when :ruby then
29
+ case @startTok.id
30
+ when :PAREN_O then
31
+ "(#{innerTxt})"
32
+ when :SQUARE_O then
33
+ "(#{innerTxt}).floor.to_r"
34
+ else
35
+ raise "Unknown delimiter #{@startTok.id}"
36
+ end
37
+ else
38
+ nil
39
+ end
40
+ end
41
+
42
+ # @see Calcula::Expr#children
43
+ # @param (see Calcula::Expr#children)
44
+ # @return (see Calcula::Expr#children)
45
+ def children
46
+ [@inner]
47
+ end
48
+ end
@@ -1,39 +1,39 @@
1
1
  require_relative "../Expr"
2
2
 
3
- module Calcula::Exprs
4
- class FuncExpr < Calcula::Expr
3
+ # Expression for functions and lambda expression
4
+ #
5
+ # @author Paul T.
6
+ class Calcula::Exprs::FuncExpr < Calcula::Expr
5
7
 
6
- # name: IdentExpr | Nil (for lambdas), params: ParamsExpr, action: Expr
7
- def initialize(name, params, action)
8
- @name = name
9
- @params = params
10
- @action = action
11
- end
12
-
13
- def to_s()
14
- return "\\#{@params.to_s}(#{@action.to_s})" if @name == nil
15
- return "#{@name.to_s}(#{@params.to_s})=#{@action.to_s}"
16
- end
17
-
18
- def to_tree()
19
- return "(lambda #{@params.to_tree} #{@action.to_tree})" if @name == nil
20
- return "(func #{@name.to_tree} #{@params.to_tree} #{@action.to_tree})"
21
- end
22
-
23
- def exec(binding)
24
- if @name == nil then
25
- # We return it (its a lambda function afterall...)
26
- else
27
- # We do not invoke this function. We just add it to the `binding`
28
- end
29
- end
8
+ # @param params [Calcula::Exprs::ParamsExpr] Parameters to the function
9
+ # @param action [Calcula::Expr] The body of the function
10
+ def initialize(params, action)
11
+ @params = params
12
+ @action = action
13
+ end
30
14
 
31
- def children()
32
- [@name, @params, @action]
15
+ # @see Calcula::Expr#to_s
16
+ # @param (see Calcula::Expr#to_s)
17
+ # @return (see Calcula::Expr#to_s)
18
+ def to_s(form: :src)
19
+ paramsTxt = @params.to_s(form: form)
20
+ actionTxt = @action.to_s(form: form)
21
+ case form
22
+ when :src then
23
+ "\\#{paramsTxt}(#{actionTxt})"
24
+ when :tree then
25
+ "(lambda #{paramsTxt} #{actionTxt})"
26
+ when :ruby then
27
+ "->#{paramsTxt}{#{actionTxt}}"
28
+ else
29
+ nil
33
30
  end
31
+ end
34
32
 
35
- def self.mkLambda(params, action)
36
- FuncExpr.new(nil, params, action)
37
- end
33
+ # @see Calcula::Expr#children
34
+ # @param (see Calcula::Expr#children)
35
+ # @return (see Calcula::Expr#children)
36
+ def children
37
+ [@params, @action]
38
38
  end
39
39
  end
@@ -1,27 +1,35 @@
1
1
  require_relative "../Expr"
2
2
 
3
- module Calcula::Exprs
4
- class IdentExpr < Calcula::Expr
3
+ # Expression for identifiers
4
+ #
5
+ # @author Paul T.
6
+ class Calcula::Exprs::IdentExpr < Calcula::Expr
5
7
 
6
- # name: Token
7
- def initialize(name)
8
- @name = name
9
- end
8
+ # @param name [Calcula::Token] This token should have the type ID
9
+ def initialize(name)
10
+ @name = name
11
+ end
10
12
 
11
- def to_s()
13
+ # @see Calcula::Expr#to_s
14
+ # @param (see Calcula::Expr#to_s)
15
+ # @return (see Calcula::Expr#to_s)
16
+ def to_s(form: :src)
17
+ case form
18
+ when :src then
12
19
  @name.text
13
- end
14
-
15
- def to_tree()
20
+ when :tree then
16
21
  "(ident #{@name.text})"
22
+ when :ruby then
23
+ @name.text.tr("'", "_")
24
+ else
25
+ nil
17
26
  end
27
+ end
18
28
 
19
- def exec(binding)
20
- binding[@name.text]
21
- end
22
-
23
- def children()
24
- []
25
- end
29
+ # @see Calcula::Expr#children
30
+ # @param (see Calcula::Expr#children)
31
+ # @return (see Calcula::Expr#children)
32
+ def children
33
+ []
26
34
  end
27
35
  end
data/lib/Exprs/NumExpr.rb CHANGED
@@ -1,27 +1,35 @@
1
1
  require_relative "../Expr"
2
2
 
3
- module Calcula::Exprs
4
- class NumExpr < Calcula::Expr
3
+ # Expression for representing real numbers
4
+ #
5
+ # @author Paul T.
6
+ class Calcula::Exprs::NumExpr < Calcula::Expr
5
7
 
6
- # num: Token
7
- def initialize(num)
8
- @num = num
9
- end
8
+ # @param num [Calcula::Token] The token should have the type of NUM
9
+ def initialize(num)
10
+ @num = num
11
+ end
10
12
 
11
- def to_s()
13
+ # @see Calcula::Expr#to_s
14
+ # @param (see Calcula::Expr#to_s)
15
+ # @return (see Calcula::Expr#to_s)
16
+ def to_s(form: :src)
17
+ case form
18
+ when :src then
12
19
  @num.text
13
- end
14
-
15
- def to_tree()
20
+ when :tree then
16
21
  "(num #{@num.text})"
22
+ when :ruby then
23
+ "#{@num.text}r"
24
+ else
25
+ nil
17
26
  end
27
+ end
18
28
 
19
- def exec(binding)
20
- return @num.text.to_f
21
- end
22
-
23
- def children()
24
- []
25
- end
29
+ # @see Calcula::Expr#children
30
+ # @param (see Calcula::Expr#children)
31
+ # @return (see Calcula::Expr#children)
32
+ def children
33
+ []
26
34
  end
27
35
  end