diff --git a/playground/apla-lang.g b/playground/apla-lang.g new file mode 100644 index 0000000..f302dc2 --- /dev/null +++ b/playground/apla-lang.g @@ -0,0 +1,429 @@ +//From: https://github.com/AplaProject/apla-lang/blob/23ce26c4392162ec67fa5ca27b6971369eeb9723/parser/parser.y + +// Identifiers + literals +%token IDENT // foobar +%token ENV // $foobar +%token CALL // foobar( +%token CALLCONTRACT // @foobar( +%token INDEX // foobar[ +%token INT // 314 +%token FLOAT // 3.14 +%token STRING // "string" +%token QSTRING // `string` +%token TRUE // true +%token FALSE // false + +// Delimiters +%token NEWLINE // \n +%token COMMA // , +%token COLON // : +%token LPAREN // ( +%token RPAREN // ) +%token OBJ // @{ +%token LBRACE // { +%token RBRACE // } +%token LBRACKET // [ +%token RBRACKET // ] +%token QUESTION // ? +%token DOUBLEDOT // .. +%token DOT // . + +// Operators +%token ADD // + +%token SUB // - +%token MUL // * +%token DIV // / +%token MOD // % + +%token ADD_ASSIGN // += +%token SUB_ASSIGN // -= +%token MUL_ASSIGN // *= +%token DIV_ASSIGN // /= +%token MOD_ASSIGN // %= +%token ASSIGN // = + +%token AND // && +%token OR // || + +%token EQ // == +%token NOT_EQ // != +%token NOT // ! + +%token LT // < +%token GT // > +%token LTE // <= +%token GTE // >= + +// Keywords +%token BREAK // break +%token CONTINUE // continue +%token DATA // data +%token CONTRACT // contract +%token IF // if +%token ELIF // elif +%token ELSE // else +%token RETURN // return +%token WHILE // while +%token FUNC // func +%token FOR // for +%token IN // in +%token SWITCH // switch +%token CASE // case +%token READ // read +%token DEFAULT // default + +// Types +%token T_INT // int +%token T_BOOL // bool +%token T_STR // str +%token T_ARR // arr +%token T_MAP // map +%token T_FLOAT // float +%token T_MONEY // money +%token T_OBJECT // object +%token T_BYTES // bytes +%token T_FILE // file + +%left AND +%left OR +%left LTE GTE LT GT EQ NOT_EQ +%left ADD SUB +%left MUL DIV MOD +%right UNARYMINUS UNARYNOT + +//%start contract_declaration +%start contracts + +%% + +ordinaltype + : T_BOOL + | T_INT + | T_STR + | T_ARR + | T_MAP + | T_FLOAT + | T_MONEY + | T_OBJECT + | T_BYTES + | T_FILE + ; + +type + : ordinaltype + | type DOT ordinaltype + ; + +rettype + : /*empty*/ + | type + ; + +statements + : /*empty*/ + | statements NEWLINE + | statements switch + | statements statement NEWLINE + ; + +params + : /*empty*/ + | expr + | params COMMA expr + ; + +cntparams + : /*empty*/ + | IDENT COLON expr + | cntparams COMMA IDENT COLON expr + ; + +var + : IDENT + ; + +index + : INDEX expr RBRACKET + | index LBRACKET expr RBRACKET + ; + +else + : /*empty*/ + | ELSE LBRACE statements RBRACE + ; + +elif + : /*empty*/ + | elif ELIF expr LBRACE statements RBRACE + ; + +case + : /*empty*/ + | case CASE exprlist LBRACE statements RBRACE NEWLINE + ; + +default + : /*empty*/ + | DEFAULT LBRACE statements RBRACE + ; + +switch + : SWITCH expr NEWLINE case default + ; + +statement + : var ASSIGN expr + | var ADD_ASSIGN expr + | var SUB_ASSIGN expr + | var MUL_ASSIGN expr + | var DIV_ASSIGN expr + | var MOD_ASSIGN expr + | index ASSIGN expr + | type IDENT ASSIGN expr + | type ident_list + | IF expr LBRACE statements RBRACE elif else + | BREAK + | CONTINUE + | RETURN + | RETURN expr + | WHILE expr LBRACE statements RBRACE + | FUNC CALL par_declarations RPAREN rettype LBRACE statements RBRACE + | CALL params RPAREN + | CALLCONTRACT cntparams RPAREN + | FOR IDENT IN expr LBRACE statements RBRACE + | FOR IDENT COMMA IDENT IN expr LBRACE statements RBRACE + | FOR IDENT IN expr DOUBLEDOT expr LBRACE statements RBRACE + ; + +exprlist + : expr + | exprlist COMMA expr + ; + +exprmaplist + : STRING COLON expr + | exprmaplist COMMA STRING COLON NEWLINE expr + | exprmaplist COMMA STRING COLON expr + ; + +object + : STRING COLON exprobj + | IDENT COLON exprobj + | object COMMA STRING COLON exprobj + | object COMMA IDENT COLON exprobj + ; + +objlist + : exprobj + | objlist COMMA exprobj + ; + +exprobj + : LPAREN expr RPAREN + | INT + | FLOAT + | STRING + | QSTRING + | TRUE + | FALSE + | CALL params RPAREN + | CALLCONTRACT cntparams RPAREN + | index + | ENV + | IDENT + | LBRACE object RBRACE + | LBRACKET objlist RBRACKET + | LBRACKET object RBRACKET + ; + +expr + : LPAREN expr RPAREN + | INT + | FLOAT + | STRING + | QSTRING + | TRUE + | FALSE + | CALL params RPAREN + | CALLCONTRACT cntparams RPAREN + | index + | ENV + | IDENT + | OBJ object RBRACE + | LBRACE exprlist RBRACE + | LBRACE exprmaplist RBRACE + | QUESTION LPAREN expr COMMA expr COMMA expr RPAREN + | expr MUL expr + | expr DIV expr + | expr ADD expr + | expr SUB expr + | expr MOD expr + | expr AND expr + | expr OR expr + | expr EQ expr + | expr NOT_EQ expr + | expr LTE expr + | expr GTE expr + | expr LT expr + | expr GT expr + | SUB expr %prec UNARYMINUS + | NOT expr %prec UNARYNOT + ; + +ident_list + : IDENT + | ident_list IDENT + ; + +par_declaration + : type ident_list + ; + +par_declarations + : /*empty*/ + | par_declaration + | par_declarations COMMA par_declaration + ; + +var_declaration + : type ident_list + | type IDENT ASSIGN expr + ; + +var_declarations + : var_declaration + | var_declarations NEWLINE var_declaration + ; + +contract_data + : /*empty*/ + | DATA LBRACE NEWLINE var_declarations NEWLINE RBRACE NEWLINE + ; + +contract_body + : contract_data statements + ; + +contract_read + : /*empty*/ + | READ + ; + +contract_declaration + : CONTRACT IDENT contract_read LBRACE NEWLINE contract_body RBRACE + | contract_declaration NEWLINE + ; + +contracts : + contract_declaration + | contracts contract_declaration + ; + +%% + +unicodeDigit \x81 +unicodeLetter \x80 +letter [_a-zA-Z]|{unicodeLetter} +hexint 0[xX][0-9a-fA-F]+ +digit [0-9]|{unicodeDigit} +int [0-9]+ +float {int}\.[0-9]+ +identifier {letter}({letter}|{digit})* +env "$"{identifier} +callcontract "@"{identifier}\( +call {identifier}\( +index {identifier}\[ +string \"([^\\"]|\\.)*\" +qstring `([^`])*` + +%% + +[ \t\r ]+ skip() +"//".* skip() +"/*"(?s:.)*?"*/" skip() + +\+= ADD_ASSIGN +-= SUB_ASSIGN +\*= MUL_ASSIGN +\/= DIV_ASSIGN +%= MOD_ASSIGN += ASSIGN + +\n NEWLINE +; NEWLINE +,[ \t\r]*\n? COMMA +: COLON +\.\. DOUBLEDOT +\. DOT +\? QUESTION +\([ \t]*\n? LPAREN +\n[ \t]*\) RPAREN +\) RPAREN +@\{[ \t]*\n? OBJ +\{ LBRACE +\} RBRACE +\[[ \t]*\n? LBRACKET +\] RBRACKET + +&& AND +\|\| OR + +\+[ \t\r]*\n? ADD +-[ \t\r]*\n? SUB +\*[ \t\r]*\n? MUL +\/[ \t\r]*\n? DIV +%[ \t\r]*\n? MOD + +==[ \t\r]*\n? EQ +!=[ \t\r]*\n? NOT_EQ +! NOT + +\<=[ \t\r]*\n? LTE +>=[ \t\r]*\n? GTE +\<[ \t\r]*\n? LT +>[ \t\r]*\n? GT + +break BREAK +continue CONTINUE +data DATA +contract CONTRACT +while WHILE +if IF +elif ELIF +else ELSE +return RETURN +true TRUE +false FALSE +func FUNC +for FOR +in IN +switch SWITCH +case CASE +read READ +default DEFAULT + +bool T_BOOL +int T_INT +hexint T_INT +str T_STR +arr T_ARR +map T_MAP +float T_FLOAT +money T_MONEY +obj T_OBJECT +bytes T_BYTES +file T_FILE + +{float} FLOAT +{hexint} INT +{int} INT +{env} ENV +{string} STRING +{qstring} QSTRING +{call} CALL +{callcontract} CALLCONTRACT +{index} INDEX + +{identifier} IDENT + +%% diff --git a/playground/index.js b/playground/index.js index e619c43..3eae21e 100644 --- a/playground/index.js +++ b/playground/index.js @@ -63,6 +63,7 @@ const sampleList = [ ["Ansi C parser", "cparser.g", "test.c", "ace/mode/c_cpp"], ["Ansi C c2go parser", "cc-c2go.g", "test.c", "ace/mode/c_cpp"], ["Antlr4.5 parser", "antlr-v4.5.g", "test.antlr", "ace/mode/yaml"], + ["Apla-lang parser", "apla-lang.g", "test.apla-lang", "ace/mode/text"], ["ArangoDB AQL parser", "arangodb-aql.g", "test.arangodb-aql", "ace/mode/text"], ["AS3 parser (partially working)", "as3-parser.g", "test.as3-parser", "ace/mode/c_cpp"], ["Asymptote camp parser", "asymptote-camp.g", "test.asymptote-camp", "ace/mode/text"], @@ -300,6 +301,7 @@ const sampleList = [ ["SQLite3 parser (partially working)", "sqlite3.g", "test.sqlite3", "ace/mode/sql"], ["S/SL parser", "s-sl.g", "test.s-sl", "ace/mode/tex"], ["Stanc3 parser", "stanc3-parser.g", "test.stanc3", "ace/mode/text"], + ["Streem-lang parser", "streem-lang.g", "test.streem-lang", "ace/mode/text"], ["SuperC C parser", "SuperC_cparser.g", "test.c", "ace/mode/c_cpp"], ["Tablegen-LLVM parser (partially working)", "tablegen-llvm.g", "test.tablegen-llvm", "ace/mode/yaml"], ["Tang parser (partially working)", "tangParser.g", "test.tangParser", "ace/mode/c_cpp"], diff --git a/playground/streem-lang.g b/playground/streem-lang.g new file mode 100644 index 0000000..c6cfc70 --- /dev/null +++ b/playground/streem-lang.g @@ -0,0 +1,378 @@ +//From: https://github.com/matz/streem/blob/d022e833335e490bd1dccf0e3bfff71eb50a40bd/src/parse.y +/* +** parse.y - streem parser +** +** See Copyright Notice in LICENSE file. +*/ + +/*Tokens*/ +%token identifier +%token keyword_case +%token keyword_class +%token keyword_def +%token keyword_else +%token keyword_emit +%token keyword_false +%token keyword_if +%token keyword_import +%token keyword_method +%token keyword_namespace +%token keyword_new +%token keyword_nil +%token keyword_return +%token keyword_skip +%token keyword_true +%token label +%token lit_number +%token lit_string +%token lit_symbol +%token lit_time +%token '\n' +%token op_amper +%token op_and +%token op_bar +//%token op_colon2 +%token op_div +%token op_eq +%token op_ge +%token op_gt +%token op_lambda +%token op_lambda2 +%token op_lambda3 +//%token op_lasgn +%token op_le +%token op_lt +%token op_minus +%token op_mod +%token op_mult +%token op_neq +%token op_or +%token op_plus +%token op_rasgn + +%nonassoc /*1*/ op_LOWEST +%right /*2*/ op_lambda op_lambda2 op_lambda3 +%right /*3*/ keyword_else +%right /*4*/ keyword_if +%left /*5*/ op_bar +%left /*6*/ op_amper +%left /*7*/ op_or +%left /*8*/ op_and +%nonassoc /*9*/ op_eq op_neq +%left /*10*/ op_lt op_le op_gt op_ge +%left /*11*/ op_plus op_minus +%left /*12*/ op_mult op_div op_mod +%right /*13*/ '!' '~' + +%start program + +%% + +program : + topstmts + ; + +topstmts : + topstmt_list opt_terms + | terms topstmt_list opt_terms + | opt_terms + ; + +topstmt_list : + topstmt + | topstmt_list terms topstmt + ; + +topstmt : + keyword_namespace identifier '{' topstmts '}' + | keyword_class identifier '{' topstmts '}' + | keyword_import identifier + | keyword_method fname '(' opt_f_args ')' '{' stmts '}' + | keyword_method fname '(' opt_f_args ')' '=' expr + | stmt + ; + +stmts : + stmt_list opt_terms + | terms stmt_list opt_terms + | opt_terms + ; + +stmt_list : + stmt + | stmt_list terms stmt + ; + +stmt : + var '=' expr + | keyword_def fname '(' opt_f_args ')' '{' stmts '}' + | keyword_def fname '(' opt_f_args ')' '=' expr + | keyword_def fname '=' expr + | expr op_rasgn var + | keyword_skip + | keyword_emit opt_args + | keyword_return opt_args + | expr + ; + +var : + identifier + ; + +fname : + identifier + | lit_string + ; + +expr : + expr op_plus /*11L*/ expr + | expr op_minus /*11L*/ expr + | expr op_mult /*12L*/ expr + | expr op_div /*12L*/ expr + | expr op_mod /*12L*/ expr + | expr op_bar /*5L*/ expr + | expr op_amper /*6L*/ expr + | expr op_gt /*10L*/ expr + | expr op_ge /*10L*/ expr + | expr op_lt /*10L*/ expr + | expr op_le /*10L*/ expr + | expr op_eq /*9N*/ expr + | expr op_neq /*9N*/ expr + | op_plus /*11L*/ expr %prec '!' /*13R*/ + | op_minus /*11L*/ expr %prec '!' /*13R*/ + | '!' /*13R*/ expr + | '~' /*13R*/ expr + | expr op_and /*8L*/ expr + | expr op_or /*7L*/ expr + | '(' opt_f_args op_lambda2 /*2R*/ expr + | '(' opt_f_args op_lambda3 /*2R*/ stmts '}' + | keyword_if /*4R*/ condition expr opt_else + | primary + ; + +condition : + '(' expr ')' + ; + +opt_else : + %prec keyword_else /*3R*/ /*empty*/ + | keyword_else /*3R*/ expr %prec keyword_else /*3R*/ + ; + +opt_args : + /*empty*/ + | args + ; + +arg : + expr + | label expr + | op_mult /*12L*/ expr + ; + +args : + arg + | args ',' arg + ; + +primary : + lit_number + | lit_string + | lit_symbol + | lit_time + | var + | '(' expr ')' + | '[' args ']' + | '[' ']' + | block + | keyword_nil + | keyword_true + | keyword_false + | keyword_new identifier '[' opt_args ']' + | fname block + | fname '(' opt_args ')' opt_block + | primary '.' fname '(' opt_args ')' opt_block + | primary '.' fname opt_block + | primary '.' '(' opt_args ')' opt_block + | op_amper /*6L*/ fname + ; + +opt_block : + /*empty*/ + | block + ; + +pterm : + var + | lit_number + | lit_string + | keyword_nil + | keyword_true + | keyword_false + | '[' ']' + | '[' '@' identifier ']' + | '[' pattern ']' + | '[' '@' identifier pattern ']' + | pterm '@' identifier + ; + +pary : + pterm + | pary ',' pterm + ; + +pstruct : + label pterm + | pstruct ',' label pterm + ; + +pattern : + pary + | pary ',' op_mult /*12L*/ pterm + | pary ',' op_mult /*12L*/ pterm ',' pary + | op_mult /*12L*/ pterm + | op_mult /*12L*/ pterm ',' pary + | pstruct + | pstruct ',' op_mult /*12L*/ pterm + ; + +cparam : + op_lambda /*2R*/ + | keyword_if /*4R*/ expr op_lambda /*2R*/ + | pattern op_lambda /*2R*/ + | pattern keyword_if /*4R*/ expr op_lambda /*2R*/ + ; + +case_body : + keyword_case cparam stmts + | case_body keyword_case cparam stmts + ; + +block : + '{' stmts '}' + | '{' bparam stmts '}' + | '{' case_body '}' + | '{' case_body keyword_else /*3R*/ op_lambda /*2R*/ stmts '}' + ; + +bparam : + op_lambda /*2R*/ + | f_args op_lambda /*2R*/ + ; + +opt_f_args : + /*empty*/ + | f_args + ; + +f_args : + var + | f_args ',' var + ; + +opt_terms : + /*empty*/ + | terms + ; + +terms : + term + | terms term + ; + +term : + ';' + | '\n' + ; + +%% + +TRAIL ([\t \n]|"#"[^\n]*"\n")* +CHAR [a-zA-Z_]|[\302-\337][\200-\277]|[\340-\357][\200-\277]{2}|[\360-\367][\200-\277]{2}|[\370-\373][\200-\277]{4}|[\374-\375][\200-\277]{5} +CHNUM ({CHAR}|[0-9]) +WORD {CHAR}{CHNUM}* +DATE [0-9]+\.[0-9]+\.[0-9]+ +TIME [0-9]+":"[0-9]+(":"[0-9]+)?(\.[0-9]+)? +TZONE "Z"|[+-][0-9]+(":"[0-9]+)? + +%% + +"+"{TRAIL} op_plus +"-"{TRAIL} op_minus +"*"{TRAIL} op_mult +"/"{TRAIL} op_div +"%"{TRAIL} op_mod +"=="{TRAIL} op_eq +"!="{TRAIL} op_neq +"<"{TRAIL} op_lt +"<="{TRAIL} op_le +">"{TRAIL} op_gt +">="{TRAIL} op_ge +"&&"{TRAIL} op_and +"||"{TRAIL} op_or +"&"{TRAIL} op_amper +//"<-"{TRAIL} op_lasgn +"=>"{TRAIL} op_rasgn +"->"{TRAIL} op_lambda +")"" "*"->"{TRAIL} op_lambda2 +")"" "*"->"" "*"{"{TRAIL} op_lambda3 +"="{TRAIL} '=' +//"::"{TRAIL} op_colon2 + +if keyword_if +{TRAIL}else{TRAIL} keyword_else +skip{TRAIL} keyword_skip +case{TRAIL} keyword_case +emit keyword_emit +return keyword_return +namespace keyword_namespace +class keyword_class +import keyword_import +def keyword_def +method keyword_method +new keyword_new +nil keyword_nil +true keyword_true +false keyword_false + +{WORD} identifier + +{WORD}: label + +{TRAIL}"|"{TRAIL} op_bar +{TRAIL}\.{TRAIL} '.' +"("{TRAIL} '(' +"["{TRAIL} '[' +"{"{TRAIL} '{' +","{TRAIL} ',' +";"{TRAIL} ';' +//":"{TRAIL} ':' +")" ')' +"]" ']' +"}" '}' +"@" '@' +"~" '~' +"!" '!' +"\n" '\n' +"#"[^\n]* skip() + +(([1-9][0-9]*)|0) lit_number + +(([1-9][0-9]*)|0)(\.[0-9][0-9]*)? lit_number + +0x[0-9a-fA-F]+ lit_number + +0o[0-7]+ lit_number + +{DATE}("T"{TIME}{TZONE}?)? lit_time + +\"([^\\\"]|\\.)*\" lit_string + +:{WORD} lit_symbol + +\"([^\\\"]|\\.)*\": label + +[ \t] skip() + + +%% diff --git a/playground/test.apla-lang b/playground/test.apla-lang new file mode 100644 index 0000000..ffd2870 --- /dev/null +++ b/playground/test.apla-lang @@ -0,0 +1,46 @@ +contract FibFor { + int a = 1 + int b = 1 + int c + int n = 10000000 + for i in 3..n-1 { + c = a + b + a = b + b = c + } + return b + n +} +//==== -1403616748667983518 +contract Over { + int i sum + while true { + i+=1 + sum += i + } + return sum +} +//==== gas is over +contract HStr { + int i sum + while i < 100000 { + sum += Len("this is" + "a string") + i+=1 + } + return sum +} +//==== 1500000 +contract Fib { + int a = 1 + int b = 1 + int c + int n = 10000000 + int i = 3 + while i < n { + c = a + b + a = b + b = c + i+=1 + } + return b + i +} +//==== -1403616748667983518 \ No newline at end of file diff --git a/playground/test.streem-lang b/playground/test.streem-lang new file mode 100644 index 0000000..ed35db0 --- /dev/null +++ b/playground/test.streem-lang @@ -0,0 +1,73 @@ +# most fundamental Streem program + +# build pipeline from stdin to stdout +stdin | stdout +# actual stream processing will happen in the event loop +# that starts after all program execution. + +# Array can be a source of Stream pipeline +["Hello World"] | stdout + +# seq(100) returns a stream of numbers from 1 to 100. +# A function object in pipeline works as a map function. +# stdout is an output destination. +seq(100) | map{x-> + if (x % 15 == 0) "FizzBuzz" + else if (x % 3 == 0) "Fizz" + else if (x % 5 == 0) "Buzz" + else x +} | stdout + +# repeat twice +seq(100) | map{x-> emit x, x} | stdout +# output: +# 1 +# 1 +# 2 +# 2 +# : + +# pick even numbers +seq(100) | each{x-> if (x % 2 == 0) {emit x}} | stdout +# output: +# 2 +# 4 +# 6 +# : + +# pick even numbers +seq(100) | filter{x-> x % 2 == 0} | stdout +# output: +# 2 +# 4 +# 6 +# : + +# simple echo server on port 8007 +tcp_server(8007) | each{s-> + s | s +} + +s = tcp_socket("localhost", 8007) +stdin | s +s | stdout + +# channel to broadcast to all clients +broadcast = chan() +tcp_server(8008) | each{s-> + broadcast | s # connect to broadcast channel + s | broadcast # broadcast incoming message +} + +each2 = { + case [], f -> [] + case [x,*y],f -> f(x); each2(y,f) +} +each2([1,2,3,4]) {x-> print(x)} + +same = { +case x,x -> true # comparison in match +case _,_ -> false # fallback +} +print(same(1,1)) +print(same(1,2))