[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: case statement for Lua
- From: Norman Ramsey <nr@...>
- Date: Sun, 13 Apr 1997 13:44:57 -0400
I felt the need for a case statement in Lua, so I added one.
Unfortunately I had to change the virtual machine as well as the
compiler, because I couldn't figure out how to duplicate the element
on top of the stack using only the existing operators.
Still, Lua is so clean that I added or changed no more than 30 lines
of code.
I borrowed syntax from Modula-3 for the case statement (with one
slight change); here's an example:
x = "bar"
case x of
| "foo" => y = 1
| "bar" => y = 2
else => y = 99
end
print(x, y)
Some day when I have another hack attack, I'll improve the patch so
you can write multiple expressions to the left of the arrow.
This is a patch file for lua-2.5. To build it, unpack the lua-2.5
distribution, change to the toplevel directory (called 'lua' in the
distribution), and run
patch < this_patch_file
(cd src; make parser)
make
Norman Ramsey
nr@cs.virginia.edu
*** ./src/luac/dump.c 1997/04/13 05:24:05 1.1
--- ./src/luac/dump.c 1997/04/13 05:24:24
***************
*** 42,47 ****
--- 42,48 ----
case PUSH0:
case PUSH1:
case PUSH2:
+ case DUP:
case PUSHLOCAL0:
case PUSHLOCAL1:
case PUSHLOCAL2:
*** ./src/luac/print.c 1997/04/13 05:23:33 1.1
--- ./src/luac/print.c 1997/04/13 05:23:48
***************
*** 3,9 ****
** print bytecodes
*/
! char* rcs_print="$Id: print.c,v 1.11 1996/11/18 11:24:16 lhf Exp $";
#include <stdio.h>
#include <stdlib.h>
--- 3,9 ----
** print bytecodes
*/
! char* rcs_print="$Id: print.c,v 1.1 1997/04/13 05:23:33 nr Exp nr $";
#include <stdio.h>
#include <stdlib.h>
***************
*** 32,37 ****
--- 32,38 ----
case PUSH0:
case PUSH1:
case PUSH2:
+ case DUP:
case PUSHINDEXED:
case STOREINDEXED0:
case ADJUST0:
*** ./src/luac/print.h 1997/04/13 05:24:50 1.1
--- ./src/luac/print.h 1997/04/13 05:25:09
***************
*** 9,14 ****
--- 9,15 ----
"PUSH0",
"PUSH1",
"PUSH2",
+ "DUP",
"PUSHBYTE",
"PUSHWORD",
"PUSHFLOAT",
*** ./src/lex.c 1997/04/13 04:44:51 1.1
--- ./src/lex.c 1997/04/13 04:46:48
***************
*** 48,53 ****
--- 48,54 ----
int token;
} reserved [] = {
{"and", AND},
+ {"case", CASE},
{"do", DO},
{"else", ELSE},
{"elseif", ELSEIF},
***************
*** 57,62 ****
--- 58,64 ----
{"local", LOCAL},
{"nil", NIL},
{"not", NOT},
+ {"of", OF},
{"or", OR},
{"repeat", REPEAT},
{"return", RETURN},
***************
*** 187,194 ****
case '=':
save_and_next();
! if (current != '=') return '=';
! else { save_and_next(); return EQ; }
case '<':
save_and_next();
--- 189,197 ----
case '=':
save_and_next();
! if (current == '>') { save_and_next(); return ARROW; }
! else if (current == '=') { save_and_next(); return EQ; }
! else return '=';
case '<':
save_and_next();
*** ./src/opcode.c 1997/04/13 05:25:23 1.1
--- ./src/opcode.c 1997/04/13 05:28:07
***************
*** 950,955 ****
--- 950,958 ----
incr_top;
break;
+ case DUP:
+ *top = *(top-1); incr_top; break;
+
case PUSHBYTE:
tag(top) = LUA_T_NUMBER; nvalue(top) = *pc++; incr_top; break;
*** ./src/opcode.h 1997/04/13 05:23:02 1.1
--- ./src/opcode.h 1997/04/13 05:20:43
***************
*** 1,6 ****
/*
** TeCGraf - PUC-Rio
! ** $Id: opcode.h,v 3.24 1996/11/01 12:46:59 roberto Exp $
*/
#ifndef opcode_h
--- 1,6 ----
/*
** TeCGraf - PUC-Rio
! ** $Id: opcode.h,v 1.1 1997/04/13 05:23:02 nr Exp nr $
*/
#ifndef opcode_h
***************
*** 23,28 ****
--- 23,29 ----
PUSH0,/* - 0.0 */
PUSH1,/* - 1.0 */
PUSH2,/* - 2.0 */
+ DUP,/* x - x x */
PUSHBYTE,/* b - (float)b */
PUSHWORD,/* w - (float)w */
PUSHFLOAT,/* f - f */
*** ./src/undump.c 1997/04/13 05:48:22 1.1
--- ./src/undump.c 1997/04/13 05:29:13
***************
*** 3,9 ****
** load bytecodes from files
*/
! char* rcs_undump="$Id: undump.c,v 1.21 1996/11/18 11:18:29 lhf Exp $";
#include <stdio.h>
#include <string.h>
--- 3,9 ----
** load bytecodes from files
*/
! char* rcs_undump="$Id: undump.c,v 1.1 1997/04/13 05:48:22 nr Exp nr $";
#include <stdio.h>
#include <string.h>
***************
*** 36,41 ****
--- 36,42 ----
case PUSH0:
case PUSH1:
case PUSH2:
+ case DUP:
case PUSHLOCAL0:
case PUSHLOCAL1:
case PUSHLOCAL2:
*** src/lua.stx 1997/04/13 04:44:51 1.1
--- src/lua.stx 1997/04/13 05:30:26
***************
*** 426,436 ****
%token WRONGTOKEN
%token NIL
! %token IF THEN ELSE ELSEIF WHILE DO REPEAT UNTIL END
%token RETURN
%token LOCAL
%token FUNCTION
%token DOTS
%token <vFloat> NUMBER
%token <vWord> STRING
%token <pTStr> NAME
--- 426,437 ----
%token WRONGTOKEN
%token NIL
! %token IF THEN ELSE ELSEIF WHILE DO REPEAT UNTIL CASE OF END
%token RETURN
%token LOCAL
%token FUNCTION
%token DOTS
+ %token ARROW
%token <vFloat> NUMBER
%token <vWord> STRING
%token <pTStr> NAME
***************
*** 515,520 ****
--- 516,523 ----
stat : IF expr1 THEN PrepJump block PrepJump elsepart END
{ codeIf($4, $6); }
+ | CASE expr1 OF case_body END
+
| WHILE {$<vLong>$=pc;} expr1 DO PrepJump block PrepJump END
{
basepc[$5] = IFFJMP;
***************
*** 553,558 ****
--- 556,569 ----
{ codeIf($4, $6); }
;
+ case_body : '|' {code_byte(DUP);} expr1 {code_byte(EQOP);} PrepJump ARROW
+ {code_byte(POP);} block PrepJump case_body
+ { codeIf($5, $9); }
+ /* should support multiple exprs */
+ | ELSE ARROW {code_byte(POP);} block
+ | /* empty */ {code_byte(POP); /* should code for fallback here */ }
+ ;
+
block : {$<vInt>$ = nlocalvar;} statlist ret
{
if (nlocalvar != $<vInt>1)