Merge branch 'master' into merge

This commit is contained in:
Andy Friesen 2023-08-04 10:02:07 -07:00
commit e25b717e54
7 changed files with 249 additions and 25 deletions

View File

@ -1,5 +1,6 @@
remote_theme: "mmistakes/minimal-mistakes@4.22.0"
remote_theme: "mmistakes/minimal-mistakes@4.24.0"
minimal_mistakes_skin: "default" #"air", "aqua", "contrast", "dark", "dirt", "neon", "mint", "plum" "sunrise"
minimal_mistakes_skin2: "dark"
url:
name: Roblox
title: Luau

View File

@ -0,0 +1,73 @@
{% capture logo_path %}{{ site.logo }}{% endcapture %}
<div class="masthead">
<div class="masthead__inner-wrap">
<div class="masthead__menu">
<nav id="site-nav" class="greedy-nav">
{% unless logo_path == empty %}
<a class="site-logo" href="{{ '/' | relative_url }}"><img src="{{ logo_path | relative_url }}"
alt="{{ site.masthead_title | default: site.title }}"></a>
{% endunless %}
<a class="site-title" href="{{ '/' | relative_url }}">
{{ site.masthead_title | default: site.title }}
{% if site.subtitle %}<span class="site-subtitle">{{ site.subtitle }}</span>{% endif %}
</a>
<ul class="visible-links">
{%- for link in site.data.navigation.main -%}
<li class="masthead__menu-item">
<a href="{{ link.url | relative_url }}" {% if link.description %} title="{{ link.description }}"
{% endif %}>{{ link.title }}</a>
</li>
{%- endfor -%}
</ul>
<i class="fas fa-fw fa-adjust" aria-hidden="true" onclick="toggleTheme()"></i>
{% if site.search == true %}
<button class="search__toggle" type="button">
<span class="visually-hidden">{{ site.data.ui-text[site.locale].search_label | default: "Toggle
search" }}</span>
<i class="fas fa-search"></i>
</button>
{% endif %}
<button class="greedy-nav__toggle hidden" type="button">
<span class="visually-hidden">{{ site.data.ui-text[site.locale].menu_label | default: "Toggle menu"
}}</span>
<div class="navicon"></div>
</button>
<ul class="hidden-links hidden"></ul>
</nav>
</div>
</div>
</div>
<link rel="stylesheet" href="{{ '/assets/css/main.css' | relative_url }}" id="theme_source">
<link rel="stylesheet alternate" href="{{ '/assets/css/theme2.css' | relative_url }}" id="theme_source_2">
<script>
let theme = localStorage.getItem('theme');
if (theme === "dark") {
localStorage.setItem('theme', 'dark');
node1 = document.getElementById('theme_source');
node2 = document.getElementById('theme_source_2');
node1.setAttribute('rel', 'stylesheet alternate');
node2.setAttribute('rel', 'stylesheet');
} else {
localStorage.setItem('theme', 'light');
}
function toggleTheme() {
node1 = document.getElementById("theme_source");
node2 = document.getElementById("theme_source_2");
if (node1.getAttribute("rel") == "stylesheet") {
node1.setAttribute("rel", "stylesheet alternate");
node2.setAttribute("rel", "stylesheet");
try { editor.setOption("theme", "dark") } catch { };
localStorage.setItem("theme", "dark");
} else {
node2.setAttribute("rel", "stylesheet alternate");
node1.setAttribute("rel", "stylesheet");
try { editor.setOption("theme", "light") } catch { };
localStorage.setItem("theme", "light");
}
return false;
}
</script>

View File

@ -2,11 +2,11 @@
<div>
<label class="header-center"><b>Input</b></label>
<br>
<textarea rows="10" cols="70" id="script"></textarea>
<textarea rows="10" cols="80" id="script"></textarea>
<div class="button-group">
<button onclick="executeScript(); return false;" class="demo-button">Run</button>
<input type="checkbox" checked="true" class="demo-button" id="output-clear" />
<label for="output-clear">Clear Output</label>
<input type="checkbox" checked="true" id="output-clear" />
</div>
</div>
<div>
@ -26,27 +26,77 @@
padding: 7px 7px;
vertical-align: middle;
}
.line-error {
background: #e65f55;
}
</style>
<!-- CodeMirror -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.0/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.0/addon/edit/matchbrackets.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.0/codemirror.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.14/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.14/addon/edit/matchbrackets.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.14/codemirror.min.css" />
<style>
.cm-s-dark.CodeMirror {background: rgb(37, 37, 37); color: rgb(204, 204, 204);}
.cm-s-dark div.CodeMirror-selected {background: rgb(11, 90, 175) !important;}
.cm-s-dark .CodeMirror-gutters {background: rgb(50, 50, 50); border-right: 0px;}
.cm-s-dark .CodeMirror-linenumber {color: rgb(204, 204, 204);}
.cm-s-dark .CodeMirror-cursor {border-left: 1px solid rgb(204, 204, 204) !important;}
.cm-s-dark span.cm-comment {color: rgb(102, 102, 102);}
.cm-s-dark span.cm-atom {color: rgb(255, 198, 0);}
.cm-s-dark span.cm-number {color: rgb(255, 198, 0);}
.cm-s-dark span.cm-keyword {color: rgb(248, 109, 124);}
.cm-s-dark span.cm-string {color: rgb(173, 241, 149);}
.cm-s-dark span.cm-variable {color: rgb(204, 204, 204);}
.cm-s-dark span.cm-builtin {color:rgb(132, 214, 247);}
.cm-s-dark span.cm-bracket {color: rgb(204, 204, 204);}
.cm-s-dark span.cm-tag {color: rgb(255, 0, 0);}
.cm-s-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
.cm-s-dark .CodeMirror-activeline-background { background: #202020; }
</style>
<style>
.cm-s-light.CodeMirror {background: white; color: black;}
.cm-s-light div.CodeMirror-selected {background: rgb(110, 161, 241) !important;}
.cm-s-light .CodeMirror-gutters {background: rgb(221, 221, 221); border-right: 0px;}
.cm-s-light .CodeMirror-linenumber {color: black;}
.cm-s-light .CodeMirror-cursor {border-left: 1px solid black !important;}
.cm-s-light span.cm-comment {color: rgb(0, 127, 9);}
.cm-s-light span.cm-atom {color: rgb(0, 127, 127);}
.cm-s-light span.cm-number {color: rgb(0, 127, 127);}
.cm-s-light span.cm-keyword {color: rgb(0, 0, 127);}
.cm-s-light span.cm-string {color: rgb(127, 0, 127);}
.cm-s-light span.cm-variable {color: black;}
.cm-s-light span.cm-builtin {color:rgb(127, 0, 0);}
.cm-s-light span.cm-bracket {color: rgb(127, 127, 0);}
.cm-s-light span.cm-tag {color: rgb(255, 0, 0);}
.cm-s-light .CodeMirror-matchingbracket { text-decoration: underline; color: black !important;}
.cm-s-light .CodeMirror-activeline-background { background: #202020; }
</style>
<!-- Luau Parser for CodeMirror -->
<script src="assets/js/luau_mode.js"></script>
<!-- CodeMirror Luau Editor (MUST BE LOADED AFTER CODEMIRROR!) -->
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("script"), {
theme: "default",
theme: localStorage.getItem('theme'),
mode: "luau",
matchBrackets: true,
lineNumbers: true,
smartIndent: true,
indentWithTabs: true,
indentUnit: 4,
indentUnit: 4
});
editor.setValue("print(\"Hello World!\")\n");
editor.addKeyMap({
@ -63,7 +113,7 @@
function output(text) {
var output_box = document.getElementById("output");
output_box.value += text.replace('stdin:', '') + "\n";
output_box.value += text + "\n";
// scroll to bottom
output_box.scrollTop = output_box.scrollHeight;
}
@ -95,6 +145,7 @@
}
}
}
</script>
<!-- Luau WASM (async fetch; should be the last line) -->
<script async src="https://github.com/Roblox/luau/releases/latest/download/Luau.Web.js"></script>

View File

@ -28,7 +28,7 @@ laststat = 'return' [explist] | 'break' | 'continue'
funcname = NAME {'.' NAME} [':' NAME]
funcbody = ['<' GenericTypeList '>'] '(' [parlist] ')' [':' ReturnType] block 'end'
parlist = bindinglist [',' '...'] | '...'
parlist = bindinglist [',' '...'] | '...' [':' (Type | GenericTypePack)]
explist = {exp ','} exp
namelist = NAME {',' NAME}
@ -83,6 +83,7 @@ GenericTypeListWithDefaults =
GenericTypePackParameterWithDefault {',' GenericTypePackParameterWithDefault}
TypeList = Type [',' TypeList] | '...' Type
BoundTypeList = [NAME ':'] Type [',' BoundTypeList] | '...' Type
TypeParams = (Type | TypePack | VariadicTypePack | GenericTypePack) [',' TypeParams]
TypePack = '(' [TypeList] ')'
GenericTypePack = NAME '...'
@ -92,6 +93,6 @@ TableIndexer = '[' Type ']' ':' Type
TableProp = NAME ':' Type
TablePropOrIndexer = TableProp | TableIndexer
PropList = TablePropOrIndexer {fieldsep TablePropOrIndexer} [fieldsep]
TableType = '{' [PropList] '}'
FunctionType = ['<' GenericTypeList '>'] '(' [TypeList] ')' '->' ReturnType
TableType = '{' Type '}' | '{' [PropList] '}'
FunctionType = ['<' GenericTypeList '>'] '(' [BoundTypeList] ')' '->' ReturnType
```

View File

@ -0,0 +1,93 @@
---
layout: single
title: "Luau Recap: July 2023"
---
Our team is still spending a lot of time working on upcoming replacement for our type inference engine as well as working on native code generation to improve runtime performance.
However, we also worked on unrelated improvements during this time that are summarized here.
[Cross-posted to the [Roblox Developer Forum](https://devforum.roblox.com/t/luau-recap-july-2023/).]
## Analysis improvements
Indexing table intersections using `x["prop"]` syntax has been fixed and no longer reports a false positive error:
```lua
type T = { foo: string } & { bar: number }
local x: T = { foo = "1", bar = 2 }
local y = x["bar"] -- This is no longer an error
```
Generic `T...` type is now convertible to `...any` variadic parameter.
This solves issues people had with variadic functions and variadic argument:
```lua
local function foo(...: any)
print(...)
end
local function bar<T...>(...: T...)
foo(...) -- This is no longer an error
end
```
We have also improved our general typechecking performance by ~17% and by additional ~30% in modules with complex types.
Other fixes include:
* Fixed issue with type `T?` not being convertible to `T | T` or `T?` which could've generated confusing errors
* Return type of `os.date` is now inferred as `DateTypeResult` when argument is "*t" or "!*t"
## Runtime improvements
Out-of-memory exception handling has been improved.
`xpcall` handlers will now actually be called with a "not enough memory" string and whatever string/object they return will be correctly propagated.
Other runtime improvements we've made:
* Performance of `table.sort` was improved further. It now guarantees N*log(N) time complexity in the worst case
* Performance of `table.concat` was improved by ~5-7%
* Performance of `math.noise` was improved by ~30%
* Inlining of functions is now possible even when they used to compute their own arguments
* Improved logic for determining whether inlining a function or unrolling a loop is profitable
## Autocomplete improvements
An issue with exported types not being suggested is now fixed.
## Debugger improvements
We have fixed the search for the closest executable breakpoint line.
Previously, breakpoints might have been skipped in `else` blocks at the end of a function.
This simplified example shows the issue:
```lua
local function foo(isIt)
if isIt then
print("yes")
else
-- When 'true' block exits the function, breakpoint couldn't be placed here
print("no")
end
end
```
## Thanks
A very special thanks to all of our open source contributors:
* [Petri Häkkinen](https://github.com/petrihakkinen)
* [JohnnyMorganz](https://github.com/JohnnyMorganz)
* [Gael](https://github.com/TheGreatSageEqualToHeaven)
* [Jan](https://github.com/Jan200101)
* [Alex Orlenko](https://github.com/khvzak)
* [mundusnine](https://github.com/mundusnine)
* [Ben Mactavsin](https://github.com/BenMactavsin)
* [RadiatedExodus](https://github.com/RealEthanPlayzDev)
* [Lodinu Kalugalage](https://github.com/imlodinu)
* [MagelessMayhem](https://github.com/MagelessMayhem)
* [Someon1e](https://github.com/Someon1e)

View File

@ -0,0 +1,8 @@
---
---
@charset "utf-8";
@import "minimal-mistakes/skins/{{ site.minimal_mistakes_skin2 | default: 'default' }}"; // skin
@import "minimal-mistakes"; // main partials

View File

@ -27,27 +27,24 @@
// long list of standard functions from lua manual
var builtins = wordRE([
"_G","_VERSION","assert","error","getfenv","getmetatable","ipairs","load", "loadstring","next","pairs","pcall",
"print","rawequal","rawget","rawset","require","select","setfenv","setmetatable","tonumber","tostring","type",
"print","rawequal","rawget","rawset","require","select","setfenv","setmetatable","tonumber","tostring","type","typeof",
"unpack","xpcall",
"coroutine.create","coroutine.resume","coroutine.running","coroutine.status","coroutine.wrap","coroutine.yield",
"debug.debug","debug.getfenv","debug.gethook","debug.getinfo","debug.getlocal","debug.getmetatable",
"debug.getregistry","debug.getupvalue","debug.setfenv","debug.sethook","debug.setlocal","debug.setmetatable",
"debug.setupvalue","debug.traceback",
"debug.info","debug.traceback",
"math.abs","math.acos","math.asin","math.atan","math.atan2","math.ceil","math.cos","math.cosh","math.deg",
"math.exp","math.floor","math.fmod","math.frexp","math.huge","math.ldexp","math.log","math.log10","math.max",
"math.min","math.modf","math.pi","math.pow","math.rad","math.random","math.randomseed","math.sin","math.sinh",
"math.sqrt","math.tan","math.tanh",
"os.clock","os.date","os.difftime","os.execute","os.exit","os.getenv","os.remove","os.rename","os.setlocale",
"os.time","os.tmpname",
"os.clock","os.date","os.difftime","os.time",
"string.byte","string.char","string.dump","string.find","string.format","string.gmatch","string.gsub",
"string.byte","string.char","string.find","string.format","string.gmatch","string.gsub",
"string.len","string.lower","string.match","string.rep","string.reverse","string.sub","string.upper",
"table.concat","table.insert","table.maxn","table.remove","table.sort"
"table.concat","table.clone","table.create","table.freeze","table.isfrozen","table.insert","table.maxn","table.move","table.remove","table.sort","table.unpack"
]);
var keywords = wordRE(["and","break","elseif","false","nil","not","or","return",
"true","function", "end", "if", "then", "else", "do",
@ -72,7 +69,7 @@
stream.skipToEnd();
return "comment";
}
if (ch == "\"" || ch == "'")
if (ch == "\"" || ch == "'" || ch == "`")
return (state.cur = string(ch))(stream, state);
if (ch == "[" && /[\[=]/.test(stream.peek()))
return (state.cur = bracketed(readBracket(stream), "string"))(stream, state);