qlang 0.0.27180000 → 0.0.27182000
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +45 -12
- data/bin/qlang +2 -0
- data/lib/qlang.rb +21 -24
- data/lib/qlang/api.rb +2 -37
- data/lib/qlang/api/func_api.rb +5 -3
- data/lib/qlang/api/integral_api.rb +4 -4
- data/lib/qlang/api/list_api.rb +4 -4
- data/lib/qlang/api/matrix_api.rb +5 -3
- data/lib/qlang/api/vector_api.rb +7 -3
- data/lib/qlang/exec.rb +3 -2
- data/lib/qlang/lexer/base.rb +30 -62
- data/lib/qlang/lexer/tokens.rb +67 -34
- data/lib/qlang/lexer/wrap_lexer.rb +6 -7
- data/lib/qlang/parser.rb +47 -30
- data/lib/qlang/parser/formula_parser.rb +1 -1
- data/lib/qlang/parser/func_parser.rb +1 -1
- data/lib/qlang/parser/list_parser.rb +1 -2
- data/lib/qlang/utils/langs.yml +7 -0
- data/lib/qlang/utils/ruby_ext.rb +46 -0
- data/lib/qlang/version.rb +1 -1
- data/spec/langs/Haskell/ex1_after.hs +74 -0
- data/spec/langs/Haskell/ex1_before.hs +74 -0
- data/spec/langs/Python/ex1_after.py +426 -0
- data/spec/langs/Python/ex1_before.py +426 -0
- data/spec/langs/R/ex1_after.R +1 -1
- data/spec/lexer/regular_expressions_spec.rb +27 -0
- data/spec/objects/vector_spec.rb +11 -0
- metadata +12 -2
data/lib/qlang/lexer/tokens.rb
CHANGED
@@ -1,45 +1,78 @@
|
|
1
1
|
module Qlang
|
2
2
|
module Lexer
|
3
3
|
module Tokens
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
# NUM
|
5
|
+
INT = /[0-9]+/
|
6
|
+
FLO = /[0-9]+\.[0-9]+/
|
7
|
+
E = /e/
|
8
|
+
PI = /pi/
|
9
|
+
NUM = /(#{FLO}|#{INT}|#{E}|#{PI})/
|
10
|
+
|
11
|
+
# FUNCTION
|
12
|
+
EMBEDDED_FUNC = /(sin|cos|tan|log)/
|
13
|
+
USER_FUNC = /[a-zA-Z]/
|
14
|
+
FUNCV = /(#{EMBEDDED_FUNC}|#{USER_FUNC})/
|
15
|
+
|
16
|
+
# VARIABLE
|
17
|
+
VAR = /([a-d]|[f-z])/
|
18
|
+
#VAR_MUL2 = /(?!pi)#{VAR}{2}/
|
19
|
+
# #VAR_MUL3 = /(?!#{EMBEDDED_FUNC})#{VAR}{3}/
|
20
|
+
# # FIX:
|
21
|
+
#VAR_MUL = /(?!#{EMBEDDED_FUNC})#{VAR_MUL2}/
|
22
|
+
|
23
|
+
# # TERM
|
24
|
+
# TERM = /(#{NUM}|#{VAR_MUL}|#{VAR_MUL})/
|
25
|
+
|
26
|
+
|
27
|
+
# OPE
|
28
|
+
PLS = /\+/
|
29
|
+
SUB = /-/
|
30
|
+
MUL = /\*/
|
31
|
+
DIV = /\//
|
32
|
+
EXP = /(\*\*|\^)/
|
33
|
+
OPE = /(#{PLS}|#{SUB}|#{MUL}|#{DIV}|#{EXP})/
|
34
|
+
|
35
|
+
VARNUM = /(#{NUM}|#{VAR})/
|
9
36
|
ANYSP = ' *'
|
10
|
-
ANYSTR =
|
11
|
-
NONL =
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
37
|
+
ANYSTR = /.+/
|
38
|
+
NONL = /[^\r\n]/
|
39
|
+
|
40
|
+
LPRN = /\(/
|
41
|
+
RPRN = /\)/
|
42
|
+
PRN = /(#{LPRN}|#{RPRN})/
|
43
|
+
|
44
|
+
LBRC = /\{/
|
45
|
+
RBRC = /\}/
|
46
|
+
BRC = /(#{LBRC}|#{RBRC})/
|
47
|
+
|
48
|
+
CLN = /\:/
|
49
|
+
SCLN = /;/
|
50
|
+
CMA = /\,/
|
51
|
+
SP = / /
|
52
|
+
|
53
|
+
# TODO: what is better
|
54
|
+
class Util
|
55
|
+
def self.string_out(str, partition)
|
56
|
+
/#{ANYSP}#{str}(#{ANYSP}#{partition}#{ANYSP}#{str})*#{ANYSP}/
|
25
57
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
VARNUMS_BY_CMA = VARNUM.line_by(CMA)
|
30
|
-
NUMS_BY_SP = NUM.line_by(SP)
|
31
|
-
|
32
|
-
# THIRD TOKEN
|
33
|
-
class ::String
|
34
|
-
def func_call
|
35
|
-
"#{FUNCV}#{LPRN}#{ANYSP}#{self}#{ANYSP}#{RPRN}"
|
58
|
+
|
59
|
+
def self.func_call(args)
|
60
|
+
/#{FUNCV}#{LPRN}#{ANYSP}#{args}#{ANYSP}#{RPRN}/
|
36
61
|
end
|
37
62
|
end
|
38
|
-
FUNCCN = NUMS_BY_CMA.func_call
|
39
|
-
FUNCCV = VARS_BY_CMA.func_call
|
40
|
-
FUNCCVN = VARNUMS_BY_CMA.func_call
|
41
63
|
|
42
|
-
|
64
|
+
NUMS_BY_CMA = Util.string_out(NUM, CMA)
|
65
|
+
VARS_BY_CMA = Util.string_out(VAR, CMA)
|
66
|
+
VARNUMS_BY_CMA = Util.string_out(VARNUM, CMA)
|
67
|
+
NUMS_BY_SP = Util.string_out(NUM, SP)
|
68
|
+
|
69
|
+
FUNCCN = Util.func_call(NUMS_BY_CMA)
|
70
|
+
FUNCCV = Util.func_call(VARS_BY_CMA)
|
71
|
+
FUNCCVN = Util.func_call(VARNUMS_BY_CMA)
|
72
|
+
|
73
|
+
NUMS_BY_SP_BY_SCLN = Util.string_out(NUMS_BY_SP, SCLN)
|
74
|
+
|
75
|
+
FORMULA = /(#{OPE}|#{FUNCV}|#{VAR}|#{NUM}|#{PRN}|#{ANYSP})+/
|
43
76
|
end
|
44
77
|
end
|
45
78
|
end
|
@@ -1,14 +1,13 @@
|
|
1
|
-
require 'pry'
|
2
1
|
module Qlang
|
3
2
|
module Lexer
|
4
3
|
class WrapLexer < Base
|
5
|
-
rule(
|
6
|
-
rule(
|
4
|
+
rule(/#{FUNCCV}#{ANYSP}=#{ANYSP}#{FORMULA}+/) { :def_func }
|
5
|
+
rule(/#{FUNCCN}/) { :eval_func }
|
7
6
|
rule(/S#{ANYSP}#{LPRN}#{ANYSTR}#{RPRN}\[#{ANYSTR}\]/) { :integral }
|
8
|
-
rule(/d\/d#{VAR}
|
9
|
-
rule(
|
10
|
-
rule(
|
11
|
-
rule(
|
7
|
+
rule(/d\/d#{VAR} #{FORMULA}/) { :differential }
|
8
|
+
rule(/#{LPRN}#{NUMS_BY_SP}#{RPRN}/) { :vector }
|
9
|
+
rule(/#{LPRN}#{NUMS_BY_SP_BY_SCLN}#{RPRN}t/) { :tmatrix }
|
10
|
+
rule(/#{LPRN}#{NUMS_BY_SP_BY_SCLN}#{RPRN}/) { :matrix }
|
12
11
|
|
13
12
|
|
14
13
|
rule(/\(/) { :LPRN }
|
data/lib/qlang/parser.rb
CHANGED
@@ -13,6 +13,9 @@ require 'qlang/parser/formula_parser'
|
|
13
13
|
|
14
14
|
module Qlang
|
15
15
|
module Parser
|
16
|
+
include Lexer::Tokens
|
17
|
+
SYM = '\w+'
|
18
|
+
ONEHASH = "#{ANYSP}#{SYM}#{CLN}#{ANYSP}#{VARNUM}#{ANYSP}" # sdf: 234
|
16
19
|
def execute(lexed)
|
17
20
|
time = Time.now
|
18
21
|
until lexed.token_str =~ /\A(:NLIN\d|:R\d)+\z/
|
@@ -36,50 +39,64 @@ module Qlang
|
|
36
39
|
when :def_func
|
37
40
|
FuncParser.execute(token_val)
|
38
41
|
end
|
39
|
-
lexed.parsed!(
|
42
|
+
lexed.parsed!(parsed, token_position)
|
40
43
|
|
41
|
-
when /:LPRN\d
|
42
|
-
|
43
|
-
|
44
|
+
when /:LPRN(\d):CONT\d:RPRN(\d)/
|
45
|
+
tokens_range = $1.to_i..$2.to_i
|
46
|
+
token_val = lexed.lexeds[tokens_range.to_a[1]][:CONT]
|
44
47
|
|
45
|
-
|
46
|
-
|
48
|
+
cont_lexed = Lexer::ContLexer.new(token_val)
|
49
|
+
cont = cont_lexed.values.join(' ')
|
50
|
+
lexed.parsed!(cont.parentheses, tokens_range)
|
47
51
|
|
48
|
-
when /:LBRC\d
|
49
|
-
|
50
|
-
|
52
|
+
when /:LBRC(\d):CONT\d:RBRC(\d)/
|
53
|
+
tokens_range = $1.to_i..$2.to_i
|
54
|
+
token_val = lexed.lexeds[tokens_range.to_a[1]][:CONT]
|
51
55
|
|
52
|
-
case
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
cont = case token_val
|
57
|
+
when %r@#{ONEHASH}(#{CMA}#{ONEHASH})*@
|
58
|
+
ListParser.execute(token_val)
|
59
|
+
else
|
60
|
+
token_val
|
61
|
+
end
|
62
|
+
|
63
|
+
lexed.parsed!(cont, tokens_range)
|
59
64
|
|
60
|
-
when /:eval_func\d/
|
61
|
-
|
62
|
-
|
63
|
-
lexed.squash_with_prn(cont_token_with_num, cont)
|
65
|
+
when /:eval_func(\d)/
|
66
|
+
token_val = lexed.get_value($1)
|
67
|
+
lexed.parsed!(token_val.parentheses, $1)
|
64
68
|
|
65
|
-
when /:differential\d/
|
66
|
-
|
67
|
-
cont = lexed.get_value(
|
69
|
+
when /:differential(\d)/
|
70
|
+
token_position = $1.to_i
|
71
|
+
cont = lexed.get_value(token_position)
|
68
72
|
cont =~ /(d\/d[a-zA-Z]) (.*)/
|
69
73
|
cont = "#{$1}(#{FormulaParser.execute($2)})"
|
70
74
|
# FIX: Refactor
|
71
75
|
#cont.gsub!(/(d\/d[a-zA-Z]) (.*)/, "\1(\2)")
|
72
|
-
lexed.
|
73
|
-
when /:CONT\d/
|
74
|
-
lexed.
|
76
|
+
lexed.parsed!(cont.parentheses, token_position)
|
77
|
+
when /:CONT(\d)/
|
78
|
+
lexed.parsed!(lexed.get_value($1), $1)
|
75
79
|
end
|
76
|
-
|
77
|
-
lexed.squash_to_cont($1, 2) if lexed.token_str =~ /(:CONT\d|:R\d)(:CONT\d|:R\d)/
|
80
|
+
lexed.squash!(($1.to_i)..($1.to_i+1)) if lexed.token_str =~ /(?::CONT|:R)(\d)(?::CONT|:R)(\d)/
|
78
81
|
end
|
79
82
|
|
80
|
-
|
81
|
-
|
83
|
+
LangEqualizer.execute(
|
84
|
+
lexed.values.join
|
85
|
+
)
|
82
86
|
end
|
83
87
|
module_function :execute
|
88
|
+
|
89
|
+
# FIXIT
|
90
|
+
class LangEqualizer
|
91
|
+
def self.execute(str)
|
92
|
+
case $meta_info.lang
|
93
|
+
when :ruby
|
94
|
+
str.gsub(/\^/, '**')
|
95
|
+
else
|
96
|
+
str
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
84
101
|
end
|
85
102
|
end
|
@@ -6,7 +6,7 @@ module Qlang
|
|
6
6
|
include Lexer::Tokens
|
7
7
|
def execute(string)
|
8
8
|
def_func, formula = string.split(/ *= */)
|
9
|
-
def_func =~
|
9
|
+
def_func =~ /(#{USER_FUNC})#{LPRN}#{ANYSP}(#{VARS_BY_CMA})#{ANYSP}#{RPRN}/
|
10
10
|
FuncApi.execute($1, $2.split(' *,'), FormulaParser.execute(formula))
|
11
11
|
end
|
12
12
|
module_function :execute
|
@@ -3,8 +3,7 @@ module Qlang
|
|
3
3
|
module ListParser
|
4
4
|
include Base
|
5
5
|
def execute(lexed)
|
6
|
-
lexed.
|
7
|
-
arys = lexed.split(',').map { |ary| [ary[0], ary[2]] }
|
6
|
+
arys = lexed.split(/ *, */).map { |e| e.split(/ *: */).map{|e2|e2.delete(' ')} }
|
8
7
|
ListApi.execute(arys)
|
9
8
|
end
|
10
9
|
module_function :execute
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class ::String
|
2
|
+
def parentheses
|
3
|
+
"(#{self})"
|
4
|
+
end
|
5
|
+
|
6
|
+
def braces
|
7
|
+
"{#{self}}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def rm(str_or_rgx)
|
11
|
+
gsub(str_or_rgx, '')
|
12
|
+
end
|
13
|
+
|
14
|
+
def rm!(str_or_rgx)
|
15
|
+
gsub!(str_or_rgx, '')
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def rms!(*str_or_rgxs)
|
20
|
+
str_or_rgxs.each do |str_or_rgx|
|
21
|
+
rm!(str_or_rgx)
|
22
|
+
end
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def split_by_sp
|
27
|
+
split(/ +/)
|
28
|
+
end
|
29
|
+
|
30
|
+
# FIX:
|
31
|
+
def equalize!
|
32
|
+
rms!(/\A +/, / +\z/)
|
33
|
+
if self =~ /\A\(/ && self =~ /\)\z/
|
34
|
+
rms!(/\A\(/, /\)\z/)
|
35
|
+
rms!(/\A +/, / +\z/)
|
36
|
+
else
|
37
|
+
self
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class ::Array
|
43
|
+
def join_by_sp
|
44
|
+
join(' ')
|
45
|
+
end
|
46
|
+
end
|
data/lib/qlang/version.rb
CHANGED
@@ -0,0 +1,74 @@
|
|
1
|
+
module Main where
|
2
|
+
|
3
|
+
filter' :: (a -> Bool) -> [a] -> [a]
|
4
|
+
filter' _ [] = []
|
5
|
+
filter' p (x:xs) | p x = x : filter' p xs
|
6
|
+
| otherwise = filter' p xs
|
7
|
+
|
8
|
+
|
9
|
+
-- pattern match for Algebraic data type
|
10
|
+
data Node = Leaf Integer | Branch Node Node deriving (Show)
|
11
|
+
|
12
|
+
depth :: Node -> Integer
|
13
|
+
depth node = case node of
|
14
|
+
Leaf _ -> 1
|
15
|
+
Branch a b -> 1 + max (depth a) (depth b)
|
16
|
+
|
17
|
+
sumLeaf :: Node -> Integer
|
18
|
+
sumLeaf node = case node of
|
19
|
+
Leaf x -> x
|
20
|
+
Branch a b -> (sumLeaf a) + (sumLeaf b)
|
21
|
+
|
22
|
+
-- Maybe monado
|
23
|
+
|
24
|
+
--data Maybee a = Justt a | Nothingg deriving (Show)
|
25
|
+
|
26
|
+
--return :: a -> Maybee a
|
27
|
+
--return a = Maybee a
|
28
|
+
|
29
|
+
--(>>=) :: Maybee a -> (a -> Maybee b) -> Maybee b
|
30
|
+
--Nothingg >>= _ = Nothingg
|
31
|
+
--Justt a >>= f = f a
|
32
|
+
|
33
|
+
add1 :: Maybe Int -> Maybe Int -> Maybe Int
|
34
|
+
add1 mx my =
|
35
|
+
case mx of
|
36
|
+
Nothing -> Nothing
|
37
|
+
Just x -> case my of
|
38
|
+
Nothing -> Nothing
|
39
|
+
Just y -> Just (x + y)
|
40
|
+
|
41
|
+
add2 :: Maybe Int -> Maybe Int -> Maybe Int
|
42
|
+
add2 mx my =
|
43
|
+
mx >>= (\x ->
|
44
|
+
my >>= (\y ->
|
45
|
+
return (x + y)))
|
46
|
+
|
47
|
+
add3 :: Maybe Int -> Maybe Int -> Maybe Int
|
48
|
+
add3 mx my = do
|
49
|
+
x <- mx
|
50
|
+
y <- my
|
51
|
+
return (x + y)
|
52
|
+
|
53
|
+
|
54
|
+
putResult x = putStrLn $ show x
|
55
|
+
|
56
|
+
|
57
|
+
main = do putResult $ filter' (> 2) [1..10]
|
58
|
+
|
59
|
+
let tree = Branch (Leaf 3) (Branch (Leaf 2) (Leaf 4))
|
60
|
+
putResult $ depth tree
|
61
|
+
putResult $ sumLeaf tree
|
62
|
+
|
63
|
+
putResult $ (Just 1) `add1` Nothing
|
64
|
+
putResult $ Nothing `add1` (Just 3)
|
65
|
+
putResult $ (Just 1) `add1` (Just 3)
|
66
|
+
putResult $ Nothing `add1` Nothing
|
67
|
+
putResult $ (Just 1) `add2` Nothing
|
68
|
+
putResult $ Nothing `add2` (Just 3)
|
69
|
+
putResult $ (Just 1) `add2` (Just 3)
|
70
|
+
putResult $ Nothing `add2` Nothing
|
71
|
+
putResult $ (Just 1) `add3` Nothing
|
72
|
+
putResult $ Nothing `add3` (Just 3)
|
73
|
+
putResult $ (Just 1) `add3` (Just 3)
|
74
|
+
putResult $ Nothing `add3` Nothing
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Main where
|
2
|
+
|
3
|
+
filter' :: (a -> Bool) -> [a] -> [a]
|
4
|
+
filter' _ [] = []
|
5
|
+
filter' p (x:xs) | p x = x : filter' p xs
|
6
|
+
| otherwise = filter' p xs
|
7
|
+
|
8
|
+
|
9
|
+
-- pattern match for Algebraic data type
|
10
|
+
data Node = Leaf Integer | Branch Node Node deriving (Show)
|
11
|
+
|
12
|
+
depth :: Node -> Integer
|
13
|
+
depth node = case node of
|
14
|
+
Leaf _ -> 1
|
15
|
+
Branch a b -> 1 + max (depth a) (depth b)
|
16
|
+
|
17
|
+
sumLeaf :: Node -> Integer
|
18
|
+
sumLeaf node = case node of
|
19
|
+
Leaf x -> x
|
20
|
+
Branch a b -> (sumLeaf a) + (sumLeaf b)
|
21
|
+
|
22
|
+
-- Maybe monado
|
23
|
+
|
24
|
+
--data Maybee a = Justt a | Nothingg deriving (Show)
|
25
|
+
|
26
|
+
--return :: a -> Maybee a
|
27
|
+
--return a = Maybee a
|
28
|
+
|
29
|
+
--(>>=) :: Maybee a -> (a -> Maybee b) -> Maybee b
|
30
|
+
--Nothingg >>= _ = Nothingg
|
31
|
+
--Justt a >>= f = f a
|
32
|
+
|
33
|
+
add1 :: Maybe Int -> Maybe Int -> Maybe Int
|
34
|
+
add1 mx my =
|
35
|
+
case mx of
|
36
|
+
Nothing -> Nothing
|
37
|
+
Just x -> case my of
|
38
|
+
Nothing -> Nothing
|
39
|
+
Just y -> Just (x + y)
|
40
|
+
|
41
|
+
add2 :: Maybe Int -> Maybe Int -> Maybe Int
|
42
|
+
add2 mx my =
|
43
|
+
mx >>= (\x ->
|
44
|
+
my >>= (\y ->
|
45
|
+
return (x + y)))
|
46
|
+
|
47
|
+
add3 :: Maybe Int -> Maybe Int -> Maybe Int
|
48
|
+
add3 mx my = do
|
49
|
+
x <- mx
|
50
|
+
y <- my
|
51
|
+
return (x + y)
|
52
|
+
|
53
|
+
|
54
|
+
putResult x = putStrLn $ show x
|
55
|
+
|
56
|
+
|
57
|
+
main = do putResult $ filter' (> 2) [1..10]
|
58
|
+
|
59
|
+
let tree = Branch (Leaf 3) (Branch (Leaf 2) (Leaf 4))
|
60
|
+
putResult $ depth tree
|
61
|
+
putResult $ sumLeaf tree
|
62
|
+
|
63
|
+
putResult $ (Just 1) `add1` Nothing
|
64
|
+
putResult $ Nothing `add1` (Just 3)
|
65
|
+
putResult $ (Just 1) `add1` (Just 3)
|
66
|
+
putResult $ Nothing `add1` Nothing
|
67
|
+
putResult $ (Just 1) `add2` Nothing
|
68
|
+
putResult $ Nothing `add2` (Just 3)
|
69
|
+
putResult $ (Just 1) `add2` (Just 3)
|
70
|
+
putResult $ Nothing `add2` Nothing
|
71
|
+
putResult $ (Just 1) `add3` Nothing
|
72
|
+
putResult $ Nothing `add3` (Just 3)
|
73
|
+
putResult $ (Just 1) `add3` (Just 3)
|
74
|
+
putResult $ Nothing `add3` Nothing
|