diff --git a/README.md b/README.md index 957aa1fc..df17dccb 100644 --- a/README.md +++ b/README.md @@ -1033,6 +1033,7 @@ APL (apl, apla, aplc, aplf, apli, apln, aplo, dyalog, dya AppleScript (applescript) Arduino Sketch (ino, pde) ArkTs (ets) +Arturo (art) AsciiDoc (adoc, asciidoc) ASP (asa, ashx, asp, axd) ASP.NET (asax, ascx, asmx, aspx, master, sitemap, webinfo) diff --git a/Unix/AUTHORS b/Unix/AUTHORS index 653cbf10..2f961569 100644 --- a/Unix/AUTHORS +++ b/Unix/AUTHORS @@ -28,4 +28,5 @@ https://github.com/kaelig https://github.com/mwiley https://github.com/michalmuskala https://github.com/Inventitech -https://github.com/zhangzqs \ No newline at end of file +https://github.com/zhangzqs +https://github.com/drkameleon \ No newline at end of file diff --git a/Unix/cloc b/Unix/cloc index 3a7a17cc..12b76c78 100755 --- a/Unix/cloc +++ b/Unix/cloc @@ -8211,6 +8211,7 @@ sub set_constants { # {{{1 'dyalog' => 'APL' , 'dyapp' => 'APL' , 'mipage' => 'APL' , + 'art' => 'Arturo' , 'as' => 'ActionScript' , 'adoc' => 'AsciiDoc' , 'asciidoc' => 'AsciiDoc' , @@ -9288,6 +9289,10 @@ sub set_constants { # {{{1 [ 'rm_comments_in_strings', '"', '//', '' ], [ 'call_regexp_common' , 'C++' ], ], + 'Arturo' => [ + [ 'remove_matches' , '^\s*;' ], + [ 'remove_inline' , ';.*$' ], + ], 'AsciiDoc' => [ [ 'remove_between_general', '////', '////' ], [ 'remove_matches' , '^\s*\/\/' ], @@ -11063,6 +11068,7 @@ sub set_constants { # {{{1 'Apex Trigger' => 1.4 , 'AppleScript' => 4.0 , 'Arduino Sketch' => 1.00, + 'Arturo' => 4.00, 'Assembly' => 0.25, 'Astro' => 3.0, 'Asymptote' => 2.50, diff --git a/Unix/t/00_C.t b/Unix/t/00_C.t index b0da07a9..5e15f4cd 100755 --- a/Unix/t/00_C.t +++ b/Unix/t/00_C.t @@ -44,6 +44,11 @@ my @Tests = ( 'ref' => '../tests/outputs/openharmony.ets.yaml', 'args' => '../tests/inputs/openharmony.ets', }, + { + 'name' => 'Arturo', + 'ref' => '../tests/outputs/Arturo.art.yaml', + 'args' => '../tests/inputs/Arturo.art', + }, { 'name' => 'AsciiDoc', 'ref' => '../tests/outputs/asciidoctor.adoc.yaml', diff --git a/cloc b/cloc index 3d22f5b5..160f05fa 100755 --- a/cloc +++ b/cloc @@ -8226,6 +8226,7 @@ sub set_constants { # {{{1 'dyalog' => 'APL' , 'dyapp' => 'APL' , 'mipage' => 'APL' , + 'art' => 'Arturo' , 'as' => 'ActionScript' , 'adoc' => 'AsciiDoc' , 'asciidoc' => 'AsciiDoc' , @@ -9303,6 +9304,10 @@ sub set_constants { # {{{1 [ 'rm_comments_in_strings', '"', '//', '' ], [ 'call_regexp_common' , 'C++' ], ], + 'Arturo' => [ + [ 'remove_matches' , '^\s*;' ], + [ 'remove_inline' , ';.*$' ], + ], 'AsciiDoc' => [ [ 'remove_between_general', '////', '////' ], [ 'remove_matches' , '^\s*\/\/' ], @@ -11069,6 +11074,7 @@ sub set_constants { # {{{1 'Apex Class' => 1.50, 'APL' => 2.50, 'ArkTs' => 2.50, + 'Arturo' => 4.00, 'AsciiDoc' => 1.50, 'AspectJ' => 1.36, 'asa' => 1.29, diff --git a/tests/inputs/Arturo.art b/tests/inputs/Arturo.art new file mode 100644 index 00000000..60b53117 --- /dev/null +++ b/tests/inputs/Arturo.art @@ -0,0 +1,417 @@ +; this is a comment +; this is another comment + +;--------------------------------- +; VARIABLES & VALUES +;--------------------------------- + +; numbers +a1: 2 +a2: 3.14 +a3: to :complex [1 2.0] ; 1.0+2.0i + +; strings +c1: "this is a string" +c2: { + this is a multiline string + that is indentation-agnostic +} +c3: {: + this is + a verbatim + multiline string + which will remain exactly + as the original +:} + +; characters +ch: `c` + +; blocks/arrays +d: [1 2 3] + +; dictionaries +e: #[ + name: "John" + surname: "Doe" + age: 34 + likes: [pizza spaghetti] +] + +; yes, functions are values too +f: function [x][ + 2 * x +] + +; colors - right, you can directly define them as well! +g1: #red +g2: #0077BF + +; dates +h: now ; 2021-05-03T17:10:48+02:00 + +; logical values +i1: true +i2: false +i3: maybe + +;--------------------------------- +; BASIC OPERATORS +;--------------------------------- + +; simple arithmetic +1 + 1 ; => 2 +8 - 1 ; => 7 +4.2 - 1.1 ; => 3.1 +10 * 2 ; => 20 +35 / 4 ; => 8 +35 // 4 ; => 8.75 +2 ^ 5 ; => 32 +5 % 3 ; => 2 + +; bitwise operators +and 3 5 ; => 1 +or 3 5 ; => 7 +xor 3 5 ; => 6 + +; pre-defined constants +pi ; => 3.141592653589793 +epsilon ; => 2.718281828459045 +null ; => null +true ; => true +false ; => false + +;--------------------------------- +; COMPARISON OPERATORS +;--------------------------------- + +; equality +1 = 1 ; => true +2 = 1 ; => false + +; inequality +1 <> 1 ; => false +2 <> 1 ; => true + +; more comparisons +1 < 10 ; => true +1 =< 10 ; => true +10 =< 10 ; => true +1 > 10 ; => false +1 >= 10 ; => false +11 >= 10 ; => true + +;--------------------------------- +; CONDITIONALS +;--------------------------------- + +; logical operators +and? true true ; => true +and? true false ; => false +or? true false ; => true +or? false false ; => false + +and? [1=2][2<3] ; => false + ; (the second block will not be evaluated) + +; simple if statements +if 2 > 1 [ print "yes!"] ; yes! +if 3 <> 2 -> print "true!" ; true! + +; if/else statements +; note it's 'if?' not 'if' +if? 2 > 3 -> print "2 is greater than 3" +else -> print "2 is not greater than 3" ; 2 is not greater than 3 + +; switch statements +switch 2 > 3 -> print "2 is greater than 3" + -> print "2 is not greater than 3" ; 2 is not greater than 3 + +a: (2 > 3)?["yes"]["no"] ; a: "no" +a: (2 > 3)? -> "yes" -> "no" ; a: "no" (exactly the same as above) + +; case/when statements +case [1] + when? [>2] -> print "1 is greater than 2. what?!" + when? [<0] -> print "1 is less than 0. nope..." + else -> print "here we are!" ; here we are! + +;--------------------------------- +; LOOPS +;--------------------------------- + +; with `loop` +arr: [1 4 5 3] +loop arr 'x [ + print ["x =" x] +] +; x = 1 +; x = 4 +; x = 5 +; x = 3 + +; with loop and custom index +loop.with:'i arr 'x [ + print ["item at position" i "=>" x] +] +; item at position 0 => 1 +; item at position 1 => 4 +; item at position 2 => 5 +; item at position 3 => 3 + +; using ranges +loop 1..3 'x -> ; since it's a single statement + print x ; there's no need for [block] notation + ; we can wrap it up using the `->` syntactic sugar + +loop `a`..`c` 'ch -> + print ch +; a +; b +; c + +; picking multiple items +loop 1..10 [x y] -> + print ["x =" x ", y =" y] +; x = 1 , y = 2 +; x = 3 , y = 4 +; x = 5 , y = 6 +; x = 7 , y = 8 +; x = 9 , y = 10 + +; looping through a dictionary +dict: #[name: "John", surname: "Doe", age: 34] +loop dict [key value][ + print [key "->" value] +] +; name -> John +; surname -> Doe +; age -> 34 + +; while loops +i: new 0 +while [i<3][ + print ["i =" i] + inc 'i +] +; i = 0 +; i = 1 +; i = 2 + +;--------------------------------- +; STRINGS +;--------------------------------- + +; case +a: "tHis Is a stRinG" +print upper a ; THIS IS A STRING +print lower a ; this is a string +print capitalize a ; THis Is a stRinG + +; concatenation +a: "Hello " ++ "World!" ; a: "Hello World!" + +; strings as an array +split "hello" ; => [h e l l o] +split.words "hello world" ; => [hello world] + +print first "hello" ; h +print last "hello" ; o + +; conversion +to :string 123 ; => "123" +to :integer "123" ; => 123 + +; joining strings together +join ["hello" "world"] ; => "helloworld" +join.with:"-" ["hello" "world"] ; => "hello-world" + +; string interpolation +x: 2 +print ~"x = |x|" ; x = 2 + +; interpolation with `print` +print ["x =" x] ; x = 2 + ; (`print` works by calculating the given block + ; and joining the different values as strings + ; with a single space between them) + +; templates +print render.template { + <||= switch x=2 [ ||> + Yes, x = 2 + <||][||> + No, x is not 2 + <||]||> +} ; Yes, x = 2 + +; matching +prefix? "hello" "he" ; => true +suffix? "hello" "he" ; => false + +contains? "hello" "ll" ; => true +contains? "hello" "he" ; => true +contains? "hello" "x" ; => false + +in? "ll" "hello" ; => true +in? "x" "hello" ; => false + +;--------------------------------- +; BLOCKS +;--------------------------------- + +; calculate a block +arr: [1 1+1 1+1+1] +@arr ; => [1 2 3] + +; execute a block +sth: [print "Hello world"] ; this is perfectly valid, + ; could contain *anything* + ; and will not be executed... + +do sth ; Hello world + ; (...until we tell it to) + +; array indexing +arr: ["zero" "one" "two" "three"] +print first arr ; zero +print arr\0 ; zero +print last arr ; three +print arr\3 ; three + +x: 2 +print get arr x ; two +print arr\[x] ; two + +; setting an array element +arr\0: "nada" +set arr 2 "dos" +print arr ; nada one dos three + +; adding elements to an array +arr: new [] +'arr ++ "one" +'arr ++ "two" +print arr ; one two + +; remove elements from an array +arr: new ["one" "two" "three" "four"] +'arr -- "two" ; arr: ["one" "three" "four"] +remove 'arr .index 0 ; arr: ["three" "four"] + +; getting the size of an array +arr: ["one" 2 "three" 4] +print size arr ; 4 + +; getting a slice of an array +print slice ["one" "two" "three" "four"] 0 1 ; one two + +; check if array contains a specific element +print contains? arr "one" ; true +print contains? arr "five" ; false + +; sorting array +arr: [1 5 3 2 4] +sort arr ; => [1 2 3 4 5] +sort.descending arr ; => [5 4 3 2 1] + +; mapping values +map 1..10 [x][2*x] ; => [2 4 6 8 10 12 14 16 18 20] +map 1..10 'x -> 2*x ; same as above +map 1..10 => [2*&] ; same as above +map 1..10 => [2*] ; same as above + +; selecting/filtering array values +select 1..10 [x][odd? x] ; => [1 3 5 7 9] +select 1..10 => odd? ; same as above + +filter 1..10 => odd? ; => [2 4 6 8 10] + ; (now, we leave out all odd numbers - + ; while select keeps them) + +; misc operations +arr: ["one" 2 "three" 4] +reverse arr ; => [4 "three" 2 "one"] +shuffle arr ; => [2 4 "three" "one"] +unique [1 2 3 2 3 1] ; => [1 2 3] +permutate [1 2 3] ; => [[1 2 3] [1 3 2] [3 1 2] [2 1 3] [2 3 1] [3 2 1]] +take 1..10 3 ; => [1 2 3] +repeat [1 2] 3 ; => [1 2 1 2 1 2] + +;--------------------------------- +; FUNCTIONS +;--------------------------------- + +; declaring a function +f: function [x][ 2*x ] +f: function [x]-> 2*x ; same as above +f: $[x]->2*x ; same as above (only using the `$` alias + ; for the `function`... function) + +; calling a function +f 10 ; => 20 + +; returning a value +g: function [x][ + if x < 2 -> return 0 + + res: 0 + loop 0..x 'z [ + res: res + z + ] + return res +] + +;--------------------------------- +; CUSTOM TYPES +;--------------------------------- + +; defining a custom type +define :person [ + ; with custom post-construction initializer + init: method [name, surname, age][ + this\name: capitalize name + this\surname: surname + this\age: age + ] + + ; custom print function + string: method [][ + render "NAME: |this\name|, SURNAME: |this\surname|, AGE: |this\age|" + ] + + ; custom comparison operator + compare: sortable 'age + + ; create a method for our custom type + sayHello: method [][ + print ["Hello" this\name] + ] +] + +; create new objects of our custom type +a: to :person ["John" "Doe" 34]! ; let's create 2 "Person"s +b: to :person ["jane" "Doe" 33]! ; and another one + +; call inner method +a\sayHello ; Hello John +b\sayHello ; Hello Jane + +; access object fields +print ["The first person's name is:" a\name] ; The first person's name is: John +print ["The second person's name is:" b\name] ; The second person's name is: Jane + +; changing object fields +a\name: "Bob" +a\sayHello ; Hello Bob + +; verifying object type +print type a ; :person +print is? :person a ; true + +; printing objects +print a ; NAME: John, SURNAME: Doe, AGE: 34 + +; sorting user objects (using custom comparator) +sort @[a b] ; Jane..., John... +sort.descending @[a b] ; John..., Jane... \ No newline at end of file diff --git a/tests/outputs/Arturo.art.yaml b/tests/outputs/Arturo.art.yaml new file mode 100644 index 00000000..bb530be8 --- /dev/null +++ b/tests/outputs/Arturo.art.yaml @@ -0,0 +1,20 @@ +--- +# github.com/AlDanial/cloc +header : + cloc_url : github.com/AlDanial/cloc + cloc_version : 2.01 + elapsed_seconds : 0.0108630657196045 + n_files : 1 + n_lines : 417 + files_per_second : 92.0550446634331 + lines_per_second : 38386.9536246516 +'Arturo' : + nFiles: 1 + blank: 81 + comment: 126 + code: 210 +SUM: + blank: 81 + comment: 126 + code: 210 + nFiles: 1 \ No newline at end of file