|
|
@ -0,0 +1,316 @@ |
|
|
|
# minproto.leg -- minimal prototype langauge for semantic experiments |
|
|
|
# |
|
|
|
# last edited: 2024-07-04 10:07:00 by piumarta on zora |
|
|
|
|
|
|
|
|
|
|
|
start = - ( s:stmt { global yysval = s } |
|
|
|
| !. { global yysval = 0 } |
|
|
|
| < (!EOL .)* > { syntaxError(yytext) } |
|
|
|
) |
|
|
|
|
|
|
|
stmt = WHILE LPAREN c:expr RPAREN s:stmt { $$ = newWhile(c, s) } |
|
|
|
| IF LPAREN c:expr RPAREN s:stmt |
|
|
|
( ELSE t:stmt { $$ = newIf(c, s, t ) } |
|
|
|
| { $$ = newIf(c, s, nil) } |
|
|
|
) |
|
|
|
| CONT EOS { $$ = newContinue() } |
|
|
|
| BREAK e:expr EOS { $$ = newBreak(e) } |
|
|
|
| BREAK EOS { $$ = newBreak(nil) } |
|
|
|
| RETURN e:expr EOS { $$ = newReturn(e) } |
|
|
|
| RETURN EOS { $$ = newReturn(nil) } |
|
|
|
| FOR LPAREN i:id IN e:expr RPAREN |
|
|
|
s:stmt { $$ = newForIn(i, e, s) } |
|
|
|
| FOR LPAREN i:id FROM a:expr |
|
|
|
TO b:expr RPAREN s:stmt { $$ = newForFromTo(i, a, b, s) } |
|
|
|
| FOR LPAREN i:expr SEMI c:expr SEMI |
|
|
|
u:expr RPAREN s:stmt { $$ = newFor(i, c, u, s) } |
|
|
|
| TRY t:stmt |
|
|
|
( CATCH LPAREN i:id RPAREN c:stmt { $$ = newTryCatch(t, i, c) } |
|
|
|
| ENSURE e:stmt { $$ = newTryEnsure(t, e) } |
|
|
|
) |
|
|
|
| RAISE e:expr EOS { $$ = newRaise(e) } |
|
|
|
| LOCAL i:id p:params b:block { $$ = newSetLocal (i, newLambda(p, b, nil, i)) } |
|
|
|
| GLOBAL i:id p:params b:block { $$ = newSetGlobal(i, newLambda(p, b, nil, i)) } |
|
|
|
| i:id p:params b:block { $$ = newSetVar (i, newLambda(p, b, nil, i)) } |
|
|
|
| v:proto DOT i:id p:params b:block { $$ = newSetProp(v, i, newLambda(p, b, v, i)) } |
|
|
|
| b:block { $$ = newBlock(b) } |
|
|
|
| e:expr EOS { $$ = e } |
|
|
|
|
|
|
|
proto = v:var ( DOT j:id !LPAREN { v = newGetProp(v, j) } |
|
|
|
)* { $$ = v } |
|
|
|
|
|
|
|
EOS = SEMI+ | &RBRACE | &ELSE | &CATCH |
|
|
|
|
|
|
|
expr = LOCAL i:id ASSIGN e:expr { $$ = newSetLocal (i, e) } |
|
|
|
| GLOBAL i:id ASSIGN e:expr { $$ = newSetGlobal(i, e) } |
|
|
|
| i:id ASSIGN e:expr { $$ = newSetVar (i, e) } |
|
|
|
| l:logor ( ASSIGN r:expr { l = assign(l, r) } |
|
|
|
| PLUSEQ r:expr { l = newBinop(opPreAdd, lvalue(l), r) } |
|
|
|
| MINUSEQ r:expr { l = newBinop(opPreSub, lvalue(l), r) } |
|
|
|
| STAREQ r:expr { l = newBinop(opPreMul, lvalue(l), r) } |
|
|
|
| SLASHEQ r:expr { l = newBinop(opPreDiv, lvalue(l), r) } |
|
|
|
| PCENTEQ r:expr { l = newBinop(opPreMod, lvalue(l), r) } |
|
|
|
| SHLEQ r:expr { l = newBinop(opPreShl, lvalue(l), r) } |
|
|
|
| SHREQ r:expr { l = newBinop(opPreShr, lvalue(l), r) } |
|
|
|
| ANDEQ r:expr { l = newBinop(opPreAnd, lvalue(l), r) } |
|
|
|
| XOREQ r:expr { l = newBinop(opPreXor, lvalue(l), r) } |
|
|
|
| OREQ r:expr { l = newBinop(opPreOr, lvalue(l), r) } |
|
|
|
)? { $$ = l } |
|
|
|
|
|
|
|
logor = l:logand ( BARBAR r:logand { l = newBinop(opLogOr, l, r) } |
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
logand = l:bitor ( ANDAND r:bitor { l = newBinop(opLogAnd, l, r) } |
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
bitor = l:bitxor ( OR r:bitxor { l = newBinop(opBitOr, l, r) } |
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
bitxor = l:bitand ( XOR r:bitand { l = newBinop(opBitXor, l, r) } |
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
bitand = l:eq ( AND r:eq { l = newBinop(opBitAnd, l, r) } |
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
eq = l:ineq ( EQ r:ineq { l = newBinop(opEq, l, r) } |
|
|
|
| NOTEQ r:ineq { l = newBinop(opNotEq, l, r) } |
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
ineq = l:shift ( LESS r:shift { l = newBinop(opLess, l, r) } |
|
|
|
| LESSEQ r:shift { l = newBinop(opLessEq, l, r) } |
|
|
|
| GRTREQ r:shift { l = newBinop(opGrtrEq, l, r) } |
|
|
|
| GRTR r:shift { l = newBinop(opGrtr, l, r) } |
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
shift = l:sum ( SHL r:sum { l = newBinop(opShl, l, r) } |
|
|
|
| SHR r:sum { l = newBinop(opShr, l, r) } |
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
sum = l:prod ( PLUS r:prod { l = newBinop(opAdd, l, r) } |
|
|
|
| MINUS r:prod { l = newBinop(opSub, l, r) } |
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
prod = l:prefix ( STAR r:prefix { l = newBinop(opMul, l, r) } |
|
|
|
| SLASH r:prefix { l = newBinop(opDiv, l, r) } |
|
|
|
| PCENT r:prefix { l = newBinop(opMod, l, r) } |
|
|
|
) * { $$ = l } |
|
|
|
|
|
|
|
prefix = PPLUS p:prefix { $$ = newBinop(opPreAdd, lvalue(p), newInteger(1)) } |
|
|
|
| MMINUS p:prefix { $$ = newBinop(opPreSub, lvalue(p), newInteger(1)) } |
|
|
|
| PLING p:prefix { $$ = newUnyop(opNot, p) } |
|
|
|
| MINUS p:prefix { $$ = newUnyop(opNeg, p) } |
|
|
|
| TILDE p:prefix { $$ = newUnyop(opCom, p) } |
|
|
|
| BQUOTE s:stmt { $$ = newUnyop(opQuasiquote, s) } |
|
|
|
| COMMAT e:expr { $$ = newUnyop(opUnquote, e) } |
|
|
|
| postfix |
|
|
|
|
|
|
|
postfix = SUPER DOT i:id a:args { $$ = newSuper(i, a) } |
|
|
|
| p:primary |
|
|
|
( LBRAK |
|
|
|
( COLON ( RBRAK { p = newGetSlice(p, nil, nil) } |
|
|
|
| e:xexpr RBRAK { p = newGetSlice(p, nil, e) } |
|
|
|
) |
|
|
|
| s:xexpr ( COLON ( RBRAK { p = newGetSlice(p, s, nil) } |
|
|
|
| e:xexpr RBRAK { p = newGetSlice(p, s, e) } |
|
|
|
) |
|
|
|
| RBRAK { p = newGetArray(p, s) } |
|
|
|
) |
|
|
|
) |
|
|
|
| DOT i:id ( a:args !LBRACE { p = newInvoke(p, i, a) } |
|
|
|
| { p = newGetProp(p, i) } |
|
|
|
) |
|
|
|
| a:args !LBRACE { p = newApply(p, a) } |
|
|
|
)* |
|
|
|
( PPLUS { p = newBinop(opPostAdd, lvalue(p), newInteger( 1)) } |
|
|
|
| MMINUS { p = newBinop(opPostAdd, lvalue(p), newInteger(-1)) } |
|
|
|
)? { $$ = p } |
|
|
|
|
|
|
|
args = LPAREN a:mkobj |
|
|
|
( RPAREN |
|
|
|
| ( k:id COLON e:xexpr { Object_put(a, k, e) } |
|
|
|
| e:xexpr { Object_push(a, e) } |
|
|
|
) |
|
|
|
( COMMA ( k:id COLON e:xexpr { Object_put(a, k, e) } |
|
|
|
| e:xexpr { Object_push(a, e) } |
|
|
|
) )* RPAREN ) { $$ = a } |
|
|
|
|
|
|
|
params = LPAREN p:mkobj |
|
|
|
( RPAREN |
|
|
|
| i:id ( COLON e:expr { Object_put(p, i, e) } |
|
|
|
| { Object_push(p, i) } |
|
|
|
) |
|
|
|
( COMMA i:id ( COLON e:expr { Object_put(p, i, e) } |
|
|
|
| { Object_push(p, i) } |
|
|
|
) |
|
|
|
)* RPAREN ) { $$ = p } |
|
|
|
|
|
|
|
mkobj = { $$ = (global new)(pObject) } |
|
|
|
|
|
|
|
primary = nil | number | string | symbol | var | lambda | subexpr | literal # | regex |
|
|
|
|
|
|
|
lambda = p:params b:block { $$ = newLambda(p, b, nil, nil) } |
|
|
|
|
|
|
|
subexpr = LPAREN e:expr RPAREN { $$ = e } |
|
|
|
| b:block { $$ = newBlock(b) } |
|
|
|
|
|
|
|
literal = LBRAK o:mkobj |
|
|
|
( RBRAK |
|
|
|
| ( ( i:id COLON e:expr { Object_put(o, i, e) } |
|
|
|
| e:expr { Object_push(o, e) } |
|
|
|
) ( COMMA ( i:id COLON e:expr { Object_put(o, i, e) } |
|
|
|
| e:expr { Object_push(o, e) } |
|
|
|
) )* )? RBRAK ) { $$ = newLiteral(o) } |
|
|
|
|
|
|
|
block = LBRACE b:mkobj |
|
|
|
( e:stmt { Object_push(b, e) } |
|
|
|
)* ( RBRACE { $$ = b } |
|
|
|
| error @{ expected("statement or \x7D", yytext) } |
|
|
|
) |
|
|
|
|
|
|
|
nil = NIL { $$ = nil } |
|
|
|
|
|
|
|
number = "-" n:unsign { $$ = neg(n) } |
|
|
|
| "+" n:number { $$ = n } |
|
|
|
| n:unsign { $$ = n } |
|
|
|
|
|
|
|
unsign = < DIGIT* '.' DIGIT+ EXP? > - { $$ = newFloat(strtod(yytext, 0)) } |
|
|
|
| "0" [bB] < BIGIT+ > - { $$ = newInteger(strtol(yytext, 0, 2)) } |
|
|
|
| "0" [xX] < HIGIT+ > - { $$ = newInteger(strtol(yytext, 0, 16)) } |
|
|
|
| "0" < OIGIT* > - { $$ = newInteger(strtol(yytext, 0, 8)) } |
|
|
|
| < DIGIT+ > - { $$ = newInteger(strtol(yytext, 0, 10)) } |
|
|
|
| "'" < char > "'" - { $$ = newInteger(_get(newStringUnescaped(yytext), String,value)[0]) } |
|
|
|
|
|
|
|
string = '"' < ( !'"' char )* > '"' - { $$ = newStringUnescaped(yytext) } |
|
|
|
|
|
|
|
char = '\\' [abefnrtv'"\[\]\\] |
|
|
|
| '\\' [0-3][0-7][0-7] |
|
|
|
| '\\' [xX] HIGIT* |
|
|
|
| '\\' [0-7][0-7]? |
|
|
|
| !'\\' . |
|
|
|
# char = "\\" ( ["'\\abfnrtv] |
|
|
|
# | [xX] HIGIT* |
|
|
|
# | [0-7][0-7]?[0-7]? |
|
|
|
# ) |
|
|
|
# | . |
|
|
|
|
|
|
|
symbol = HASH i:id { $$ = i } |
|
|
|
|
|
|
|
var = LOCAL i:id { $$ = newGetLocal (i) } |
|
|
|
| GLOBAL i:id { $$ = newGetGlobal(i) } |
|
|
|
| i:id { $$ = newGetVar (i) } |
|
|
|
|
|
|
|
id = < LETTER ALNUM* > - { $$ = intern(yytext) } |
|
|
|
|
|
|
|
# regex = SLASH a:alts SLASH { $$ = a } |
|
|
|
|
|
|
|
# alts = s:seq ( OR t:seq { s = Alt_append(t) } |
|
|
|
# )* { $$ = s } |
|
|
|
|
|
|
|
# seq = p:pre ( q:pre { s = Seq_append(t) } |
|
|
|
# )* { $$ = s } |
|
|
|
|
|
|
|
# elt = action | pre |
|
|
|
|
|
|
|
# action = b:block { $$ = newAction(b) } |
|
|
|
|
|
|
|
# pre = PLING p:pre { $$ = newNot(p) } |
|
|
|
# | AND p:pre { $$ = newAnd(p) } |
|
|
|
# | post |
|
|
|
|
|
|
|
# post = a:atom ( STAR { a = newMany(a) } |
|
|
|
# | PLUS { a = newMore(a) } |
|
|
|
# | QUERY { a = newMore(a) } |
|
|
|
# )? { $$ = a } |
|
|
|
|
|
|
|
# atom = DOT { $$ = newDot() } |
|
|
|
# | "[" ( !"]" "\\"? . )* "]" - { $$ = newClass(yytext) } |
|
|
|
# | '"' xxxxxx |
|
|
|
|
|
|
|
# class = LBRAK |
|
|
|
|
|
|
|
BIGIT = [0-1] |
|
|
|
OIGIT = [0-7] |
|
|
|
DIGIT = [0-9] |
|
|
|
HIGIT = [0-9A-Fa-f] |
|
|
|
LETTER = [A-Za-z_$?] |
|
|
|
ALNUM = LETTER | DIGIT |
|
|
|
SIGN = [-+] |
|
|
|
EXP = [eE] SIGN DIGIT+ |
|
|
|
|
|
|
|
- = SPACE* |
|
|
|
|
|
|
|
SPACE = [ \t] | EOL | SLC | MLC |
|
|
|
EOL = [\n\r] { ++lineno } |
|
|
|
SLC = "//" (!EOL .)* |
|
|
|
MLC = "/*" ( MLC | !"*/" (EOL | .))* "*/" - |
|
|
|
|
|
|
|
NIL = "nil" !ALNUM - |
|
|
|
WHILE = "while" !ALNUM - |
|
|
|
IF = "if" !ALNUM - |
|
|
|
ELSE = "else" !ALNUM - |
|
|
|
FOR = "for" !ALNUM - |
|
|
|
IN = "in" !ALNUM - |
|
|
|
FROM = "from" !ALNUM - |
|
|
|
TO = "to" !ALNUM - |
|
|
|
CONT = "continue" !ALNUM - |
|
|
|
BREAK = "break" !ALNUM - |
|
|
|
RETURN = "return" !ALNUM - |
|
|
|
TRY = "try" !ALNUM - |
|
|
|
CATCH = "catch" !ALNUM - |
|
|
|
ENSURE = "ensure" !ALNUM - |
|
|
|
RAISE = "raise" !ALNUM - |
|
|
|
GLOBAL = "global" !ALNUM - |
|
|
|
LOCAL = "local" !ALNUM - |
|
|
|
SUPER = "super" !ALNUM - |
|
|
|
|
|
|
|
BQUOTE = "`" - |
|
|
|
COMMAT = "@" - |
|
|
|
HASH = "#" - |
|
|
|
SEMI = ";" - |
|
|
|
ASSIGN = "=" ![=] - |
|
|
|
COMMA = "," - |
|
|
|
COLON = ":" ![:] - |
|
|
|
LPAREN = "(" - |
|
|
|
RPAREN = ")" - |
|
|
|
LBRAK = "[" - |
|
|
|
RBRAK = "]" - |
|
|
|
LBRACE = "{" - |
|
|
|
RBRACE = "}" - |
|
|
|
BARBAR = "||" ![=] - |
|
|
|
ANDAND = "&&" ![=] - |
|
|
|
OR = "|" ![|=] - |
|
|
|
OREQ = "|=" - |
|
|
|
XOR = "^" ![=] - |
|
|
|
XOREQ = "^=" - |
|
|
|
AND = "&" ![&=] - |
|
|
|
ANDEQ = "&=" - |
|
|
|
EQ = "==" - |
|
|
|
NOTEQ = "!=" - |
|
|
|
LESS = "<" ![<=] - |
|
|
|
LESSEQ = "<=" - |
|
|
|
GRTREQ = ">=" - |
|
|
|
GRTR = ">" ![=] - |
|
|
|
SHL = "<<" ![=] - |
|
|
|
SHLEQ = "<<=" - |
|
|
|
SHR = ">>" ![=] - |
|
|
|
SHREQ = ">>=" - |
|
|
|
PLUS = "+" ![+=] - |
|
|
|
PLUSEQ = "+=" - |
|
|
|
PPLUS = "++" - |
|
|
|
MINUS = "-" ![-=] - |
|
|
|
MINUSEQ = "-=" - |
|
|
|
MMINUS = "--" - |
|
|
|
STAR = "*" ![=] - |
|
|
|
STAREQ = "*=" - |
|
|
|
SLASH = "/" ![/=] - |
|
|
|
SLASHEQ = "/=" - |
|
|
|
PCENT = "%" ![=] - |
|
|
|
PCENTEQ = "%=" - |
|
|
|
DOT = "." ![.] - |
|
|
|
PLING = "!" ![=] - |
|
|
|
TILDE = "~" - |
|
|
|
|
|
|
|
error = - < (!EOL .)* > |
|
|
|
|
|
|
|
xexpr = expr | error @{ expected("expression", yytext) } |
|
|
|
|