From fbab8d74e8457e3313dacf44e954783bd4be7780 Mon Sep 17 00:00:00 2001 From: craftablescience Date: Fri, 26 May 2023 12:57:49 -0400 Subject: [PATCH 1/5] feat: add != as alias for ~= --- llex.c | 10 ++++++---- llex.h | 2 +- lparser.c | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/llex.c b/llex.c index 5fc39a5cde..fb88dcdc8f 100644 --- a/llex.c +++ b/llex.c @@ -42,7 +42,7 @@ static const char *const luaX_tokens [] = { "end", "false", "for", "function", "goto", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while", - "//", "..", "...", "==", ">=", "<=", "~=", + "//", "..", "...", "==", ">=", "<=", "~=", "!=", "<<", ">>", "::", "", "", "", "", "" }; @@ -505,10 +505,12 @@ static int llex (LexState *ls, SemInfo *seminfo) { if (check_next1(ls, '/')) return TK_IDIV; /* '//' */ else return '/'; } - case '~': { + case '~': + case '!': { + int c = ls->current; next(ls); - if (check_next1(ls, '=')) return TK_NE; /* '~=' */ - else return '~'; + if (check_next1(ls, '=')) return c == '~' ? TK_NE /* '~=' */ : TK_NE2 /* '!=' */; + else return c; } case ':': { next(ls); diff --git a/llex.h b/llex.h index 389d2f8635..0010f4741a 100644 --- a/llex.h +++ b/llex.h @@ -36,7 +36,7 @@ enum RESERVED { TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, /* other terminal symbols */ - TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, + TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NE2, TK_SHL, TK_SHR, TK_DBCOLON, TK_EOS, TK_FLT, TK_INT, TK_NAME, TK_STRING diff --git a/lparser.c b/lparser.c index b745f236f0..efbb5e6d15 100644 --- a/lparser.c +++ b/lparser.c @@ -1218,7 +1218,7 @@ static BinOpr getbinopr (int op) { case TK_SHL: return OPR_SHL; case TK_SHR: return OPR_SHR; case TK_CONCAT: return OPR_CONCAT; - case TK_NE: return OPR_NE; + case TK_NE: case TK_NE2: return OPR_NE; case TK_EQ: return OPR_EQ; case '<': return OPR_LT; case TK_LE: return OPR_LE; From 1c5168fd44ceb8cbcd2ad41d9b10c4e70a5d2b85 Mon Sep 17 00:00:00 2001 From: craftablescience Date: Fri, 26 May 2023 14:30:28 -0400 Subject: [PATCH 2/5] feat: add compound assignment operators (+=, -=, *=, /=, %=, ..=, ^=) --- llex.c | 40 ++++++++++++++++++++++++++++++++++------ llex.h | 3 ++- lparser.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/llex.c b/llex.c index fb88dcdc8f..912712e115 100644 --- a/llex.c +++ b/llex.c @@ -42,8 +42,9 @@ static const char *const luaX_tokens [] = { "end", "false", "for", "function", "goto", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while", - "//", "..", "...", "==", ">=", "<=", "~=", "!=", - "<<", ">>", "::", "", + "//", "..", "..=", "...", "==", ">=", "<=", "~=", "!=", + "<<", ">>", "+=", "-=", "*=", "/=", "%=", "^=", + "::", "", "", "", "", "" }; @@ -454,9 +455,13 @@ static int llex (LexState *ls, SemInfo *seminfo) { next(ls); break; } - case '-': { /* '-' or '--' (comment) */ + case '-': { /* '-' or '-=' or '--' (comment) */ next(ls); - if (ls->current != '-') return '-'; + if (ls->current == '=') { + next(ls); + return TK_SUBE; + } + else if (ls->current != '-') return '-'; /* else is a comment */ next(ls); if (ls->current == '[') { /* long comment? */ @@ -502,9 +507,30 @@ static int llex (LexState *ls, SemInfo *seminfo) { } case '/': { next(ls); - if (check_next1(ls, '/')) return TK_IDIV; /* '//' */ + if (ls->current == '=') { + next(ls); + return TK_DIVE; + } + else if (check_next1(ls, '/')) return TK_IDIV; /* '//' */ else return '/'; } + case '+': + case '*': + case '%': + case '^': { + int c = ls->current; + next(ls); + if (ls->current != '=') return c; /* '+', '*', '%', '^' */ + else { + next(ls); + switch (c) { + case '+': return TK_ADDA; /* '+=' */ + case '*': return TK_MULA; /* '*=' */ + case '%': return TK_MODA; /* '%=' */ + case '^': return TK_POWA; /* '^=' */ + } + } + } case '~': case '!': { int c = ls->current; @@ -521,11 +547,13 @@ static int llex (LexState *ls, SemInfo *seminfo) { read_string(ls, ls->current, seminfo); return TK_STRING; } - case '.': { /* '.', '..', '...', or number */ + case '.': { /* '.', '..', '..=', '...', or number */ save_and_next(ls); if (check_next1(ls, '.')) { if (check_next1(ls, '.')) return TK_DOTS; /* '...' */ + else if (check_next(ls, "=")) + return TK_CONCATA; /* '..=' */ else return TK_CONCAT; /* '..' */ } else if (!lisdigit(ls->current)) return '.'; diff --git a/llex.h b/llex.h index 0010f4741a..0443811a17 100644 --- a/llex.h +++ b/llex.h @@ -36,8 +36,9 @@ enum RESERVED { TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, /* other terminal symbols */ - TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NE2, + TK_IDIV, TK_CONCAT, TK_CONCATA, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NE2, TK_SHL, TK_SHR, + TK_ADDA, TK_SUBA, TK_MULA, TK_DIVA, TK_MODA, TK_POWA, TK_DBCOLON, TK_EOS, TK_FLT, TK_INT, TK_NAME, TK_STRING }; diff --git a/lparser.c b/lparser.c index efbb5e6d15..d3a3960829 100644 --- a/lparser.c +++ b/lparser.c @@ -1403,6 +1403,44 @@ static void restassign (LexState *ls, struct LHS_assign *lh, int nvars) { } +/* +** Parse and compile a compound assignment. +** Made by https://github.com/samhocevar +** +** compoundassign -> ( '+=' | '-=' | '*=' | '/=' | '%=' | '..=' | '^=' ) expression +*/ +static void compoundassign (LexState *ls, expdesc *v) { + int i, line, extra; + FuncState *fs = ls->fs; + expdesc e1 = *v, e2; + BinOpr op = ls->t.token == TK_ADDA ? OPR_ADD : + ls->t.token == TK_SUBA ? OPR_SUB : + ls->t.token == TK_MULA ? OPR_MUL : + ls->t.token == TK_DIVA ? OPR_DIV : + ls->t.token == TK_MODA ? OPR_MOD : + ls->t.token == TK_CONCATA ? OPR_CONCAT : + ls->t.token == TK_POWA ? OPR_POW : + OPR_NOBINOPR; + extra = fs->freereg - fs->nactvar; + for (i = 0; i < extra; ++i) + new_localvarliteral(ls, "(for compound)"); + adjustlocalvars(ls, extra); + + luaX_next(ls); + line = ls->linenumber; + + enterlevel(ls); + luaK_infix(fs, op, &e1); + expr(ls, &e2); + luaK_posfix(fs, op, &e1, &e2, line); + leavelevel(ls); + + luaK_exp2nextreg(fs, &e1); + luaK_setoneret(ls->fs, &e1); + luaK_storevar(ls->fs, v, &e1); +} + + static int cond (LexState *ls) { /* cond -> exp */ expdesc v; @@ -1797,7 +1835,17 @@ static void exprstat (LexState *ls) { FuncState *fs = ls->fs; struct LHS_assign v; suffixedexp(ls, &v.v); - if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ + if (ls->t.token == TK_ADDA || + ls->t.token == TK_SUBA || + ls->t.token == TK_MULA || + ls->t.token == TK_DIVA || + ls->t.token == TK_MODA || + ls->t.token == TK_CONCATA || + ls->t.token == TK_POWA) { + v.prev = NULL; + compoundassign(ls, &v.v); + } + else if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ v.prev = NULL; restassign(ls, &v, 1); } From dffa678fc6dc31b7924c11556683248a8c636ba4 Mon Sep 17 00:00:00 2001 From: craftablescience Date: Fri, 26 May 2023 21:01:06 -0400 Subject: [PATCH 3/5] feat: add cmake file, delete onelua.c --- CMakeLists.txt | 14 ++++++ onelua.c | 121 ------------------------------------------------- 2 files changed, 14 insertions(+), 121 deletions(-) create mode 100644 CMakeLists.txt delete mode 100644 onelua.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000..d61fe27650 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.16) +project(lua LANGUAGES C) +set(CMAKE_C_STANDARD 11) + +file(GLOB LUA_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.c" "${CMAKE_CURRENT_SOURCE_DIR}/*.h") +add_library(${PROJECT_NAME} STATIC ${LUA_SOURCES}) + +target_link_libraries(${PROJECT_NAME} PRIVATE m) + +target_include_directories(${PROJECT_NAME} + PUBLIC + "${CMAKE_CURRENT_SOURCE_DIR}") + +add_library(lua::lua ALIAS lua) diff --git a/onelua.c b/onelua.c deleted file mode 100644 index 2a43496124..0000000000 --- a/onelua.c +++ /dev/null @@ -1,121 +0,0 @@ -/* -** Lua core, libraries, and interpreter in a single file. -** Compiling just this file generates a complete Lua stand-alone -** program: -** -** $ gcc -O2 -std=c99 -o lua onelua.c -lm -** -** or -** -** $ gcc -O2 -std=c89 -DLUA_USE_C89 -o lua onelua.c -lm -** -*/ - -/* default is to build the full interpreter */ -#ifndef MAKE_LIB -#ifndef MAKE_LUAC -#ifndef MAKE_LUA -#define MAKE_LUA -#endif -#endif -#endif - - -/* -** Choose suitable platform-specific features. Default is no -** platform-specific features. Some of these options may need extra -** libraries such as -ldl -lreadline -lncurses -*/ -#if 0 -#define LUA_USE_LINUX -#define LUA_USE_MACOSX -#define LUA_USE_POSIX -#define LUA_ANSI -#endif - - -/* no need to change anything below this line ----------------------------- */ - -#include "lprefix.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* setup for luaconf.h */ -#define LUA_CORE -#define LUA_LIB -#define ltable_c -#define lvm_c -#include "luaconf.h" - -/* do not export internal symbols */ -#undef LUAI_FUNC -#undef LUAI_DDEC -#undef LUAI_DDEF -#define LUAI_FUNC static -#define LUAI_DDEC(def) /* empty */ -#define LUAI_DDEF static - -/* core -- used by all */ -#include "lzio.c" -#include "lctype.c" -#include "lopcodes.c" -#include "lmem.c" -#include "lundump.c" -#include "ldump.c" -#include "lstate.c" -#include "lgc.c" -#include "llex.c" -#include "lcode.c" -#include "lparser.c" -#include "ldebug.c" -#include "lfunc.c" -#include "lobject.c" -#include "ltm.c" -#include "lstring.c" -#include "ltable.c" -#include "ldo.c" -#include "lvm.c" -#include "lapi.c" - -/* auxiliary library -- used by all */ -#include "lauxlib.c" - -/* standard library -- not used by luac */ -#ifndef MAKE_LUAC -#include "lbaselib.c" -#include "lcorolib.c" -#include "ldblib.c" -#include "liolib.c" -#include "lmathlib.c" -#include "loadlib.c" -#include "loslib.c" -#include "lstrlib.c" -#include "ltablib.c" -#include "lutf8lib.c" -#include "linit.c" -#endif - -/* lua */ -#ifdef MAKE_LUA -#include "lua.c" -#endif - -/* luac */ -#ifdef MAKE_LUAC -#include "luac.c" -#endif From 70d1546d9168d5279a89690e3948fc92e2ca8215 Mon Sep 17 00:00:00 2001 From: craftablescience Date: Fri, 26 May 2023 21:42:21 -0400 Subject: [PATCH 4/5] fix: some compile errors --- llex.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llex.c b/llex.c index 912712e115..c912160625 100644 --- a/llex.c +++ b/llex.c @@ -459,7 +459,7 @@ static int llex (LexState *ls, SemInfo *seminfo) { next(ls); if (ls->current == '=') { next(ls); - return TK_SUBE; + return TK_SUBA; } else if (ls->current != '-') return '-'; /* else is a comment */ @@ -509,7 +509,7 @@ static int llex (LexState *ls, SemInfo *seminfo) { next(ls); if (ls->current == '=') { next(ls); - return TK_DIVE; + return TK_DIVA; } else if (check_next1(ls, '/')) return TK_IDIV; /* '//' */ else return '/'; @@ -552,7 +552,7 @@ static int llex (LexState *ls, SemInfo *seminfo) { if (check_next1(ls, '.')) { if (check_next1(ls, '.')) return TK_DOTS; /* '...' */ - else if (check_next(ls, "=")) + else if (check_next1(ls, '=')) return TK_CONCATA; /* '..=' */ else return TK_CONCAT; /* '..' */ } From c2c52fe24e35031a4b99c739519561e582ccf2e0 Mon Sep 17 00:00:00 2001 From: craftablescience Date: Fri, 26 May 2023 21:55:49 -0400 Subject: [PATCH 5/5] fix: let the parent project handle linking with math lib --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d61fe27650..96cff23d61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,8 +5,6 @@ set(CMAKE_C_STANDARD 11) file(GLOB LUA_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.c" "${CMAKE_CURRENT_SOURCE_DIR}/*.h") add_library(${PROJECT_NAME} STATIC ${LUA_SOURCES}) -target_link_libraries(${PROJECT_NAME} PRIVATE m) - target_include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")