diff --git a/docs/Compatibility.md b/docs/Compatibility.md index b8f7cb632..0b5c2471a 100644 --- a/docs/Compatibility.md +++ b/docs/Compatibility.md @@ -2,9 +2,10 @@ sidebar_position: 10 --- -## How compatible with Lua is Pluto? -Pluto is compatible with most Lua source code. However, it's imperfect. Due to that, Pluto has several compatibility options. -### Where are the incompatibilities? +Pluto aims to be source- and bytecode-compatible with existing Lua code such that it can simply be used as a drop-in replacement for Lua, and Lua modules can simply be used in Pluto codebases. In the vast majority of cases, we do succeed, but there are a few things to be aware of. + +## New Keywords + Pluto adds the following reserved tokens: - `switch` - `continue` @@ -18,14 +19,13 @@ Pluto adds the following reserved tokens: Which means you can't use them as identifiers. They can still be used with short-hand table indexes and goto labels because Pluto [allows reserved keywords to be used in those contexts](QoL%20Improvements/Reserved%20Identifiers). -### How to fix it? -All of these incompatible keywords can be disabled: +### Mitigations + - **For Integrators:** Check your `luaconf.h` file to find the relevant macros under the "Compatibility" heading. - **For Scripters:** Use `pluto_use` in the source files. `-- @pluto_use * = false` to simply disable all incompatible keywords. - **For Users:** Pass the `-c` flag to `pluto` or `plutoc`. -## For Scripters -Scripters are given final say in how Compatibility Mode works within their scripts. +The following sections will go more in-depth on source-level mitigations (for scripters). ### Compile-time Configuration (pluto_use) You can change the meaning of Pluto's reserved tokens at any point in your scripts using the `--@pluto_use` comment or `pluto_use` statement. @@ -72,4 +72,32 @@ These are what they look like: - `pluto_parent` - `pluto_export` - `pluto_try` -- `pluto_catch` \ No newline at end of file +- `pluto_catch` + +## Default Table Metatable + +This is [a feature in Pluto](Runtime%20Environment/Global%20&%20Base#default-metatables) that, by itself, is a benign QoL improvement for developers. However, in combination with our added standard library functions like [table.min](Runtime%20Environment/Table#tablemin), it can be an unexpected semantic change: + +```pluto showLineNumbers +local function roll(opts) + return math.random(opts.min or 1, opts.max or 100) +end +print(roll{ max = 10 }) +``` +``` +pluto: test.pluto:2: bad argument #1 to 'random' (number expected, got function) +stack traceback: + [C]: in function 'math.rand' + test.pluto:2: in local 'roll' + test.pluto:4: in main chunk +``` + +Integrators can disable this feature by defining the `PLUTO_NO_DEFAULT_TABLE_METATABLE` macro in their luaconf.h or build config, to aid in a smooth transition, should scripts in their ecosystem require it. + +Scripters are advised to use `rawget` and/or `type` to better codify their expectations. For example, the example above seems to care only about providing fallback values and not at all about type-checking, so `rawget` would be an excellent fit for it: +```pluto +local function roll(opts) + return math.random(rawget(opts, "min") or 1, rawget(opts, "max") or 100) +end +print(roll{ max = 10 }) +``` diff --git a/src/theme/pluto.js b/src/theme/pluto.js index 7ba9d18c8..ba6153333 100644 --- a/src/theme/pluto.js +++ b/src/theme/pluto.js @@ -9,7 +9,7 @@ Prism.languages.pluto = { /(?<=\|>)\s[\w.:]+/, // |> func /\b(function|enum|class)\b/, /\b(os\.platform|json\.null|json\.withnull|json\.withorder)\b/, // standard library constants - /\b(debug|table|string|number|io|os|coroutine|_VERSION|_PVERSION|_PSOUP)\b/, // standard library + type hints + /\b(debug|table|string|math|number|io|os|coroutine|_VERSION|_PVERSION|_PSOUP)\b/, // standard library + type hints ], 'attr-value': /<(const|close|nodiscard)>/, 'string': {