forked from Mirror/wren
Redo site design.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
# Intermediate files directory.
|
||||
build/
|
||||
build_xcode/
|
||||
.sass-cache/
|
||||
|
||||
# Built applications.
|
||||
wren
|
||||
|
||||
2
Makefile
2
Makefile
@ -12,7 +12,7 @@ OBJECTS = $(SOURCES:.c=.o)
|
||||
DEBUG_OBJECTS = $(addprefix build/debug/, $(notdir $(OBJECTS)))
|
||||
RELEASE_OBJECTS = $(addprefix build/release/, $(notdir $(OBJECTS)))
|
||||
|
||||
.PHONY: all clean test docs corelib
|
||||
.PHONY: all clean test docs builtin
|
||||
|
||||
all: release
|
||||
|
||||
|
||||
@ -18,9 +18,9 @@ Most languages in the first bucket aren't suitable for production use. (Servers
|
||||
|
||||
## Why is Wren fast?
|
||||
|
||||
Wren is in the second bucket. If you want to have a simple implementation but be fast enough for real use, that's the natural home. Within that bucket, Wren's performance is quite competitive despite being much younger and with a much smaller, simpler codebase. What's the trick?
|
||||
Wren is in the second bucket. If you want to have a simple implementation but be fast enough for real use, that's the sweet spot. Within that bucket, Wren's performance is quite competitive despite being much younger and with a much smaller, simpler codebase.
|
||||
|
||||
There are a few things Wren has to give it a leg up:
|
||||
Wren has a few tricks here to give it a leg up:
|
||||
|
||||
### A compact value representation
|
||||
|
||||
@ -58,13 +58,13 @@ On compilers that support it, Wren's core bytecode interpreter loop will use som
|
||||
|
||||
Doing that using an actual `switch` wreaks havoc with the CPU's branch predictor: there is basically a single branch point for the entire interpreter. That quickly saturates the predictor and it just gets confused and fails to predict anything, which leads to more CPU stalls and pipeline flushes.
|
||||
|
||||
Using computed gotos gives you a separate branch point at the end of each instruction. Each gets its own branch prediction, which will often succeed since some instruction pairs are more common than others. In my rough testing, this made a 5-10% performance difference.
|
||||
Using computed gotos gives you a separate branch point at the end of each instruction. Each gets its own branch prediction, which oftens succeed since some instruction pairs are more common than others. In my rough testing, this made a 5-10% performance difference.
|
||||
|
||||
### A single-pass compiler
|
||||
|
||||
Compile time is a relatively small component of a language's performance: code only has to be compiled once but a given line of code may be run many many times. Still, Wren's compiler is quite fast.
|
||||
|
||||
It's modeled after Lua's compiler. Instead of tokenizing and then parsing to create a bunch AST structures which are then consumed and deallocated by later phases, it emits code directly during parsing. This means it does almost no memory allocation during a parse and has very little overhead.
|
||||
It's modeled after Lua's compiler. Instead of tokenizing and then parsing to create a bunch of AST structures which are then consumed and deallocated by later phases, it emits code directly during parsing. This means it does almost no memory allocation during a parse and has very little overhead.
|
||||
|
||||
## Why don't other languages do this?
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ Here's the same example in Wren:
|
||||
The [performance page](performance.html) has more details, but the short answer is that bytecode is a nice trade-off between performance and simplicity. Also:
|
||||
|
||||
* Many devices like iPhones and game consoles don't allow executing code generated at runtime, which rules out a JIT.
|
||||
* I think fibers are a really powerful tool, and implementing them is straightforward in a bytecode VM which doesn't use the native stack.
|
||||
* I think fibers are a really powerful tool, and implementing them is straightforward in a bytecode VM that doesn't use the native stack.
|
||||
|
||||
## What about your other languages?
|
||||
|
||||
|
||||
@ -1,182 +0,0 @@
|
||||
body, code, h1, h2, h3, p, pre, tt {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font: 36px "Sanchez", helvetica, arial, sans-serif;
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font: normal 24px "Sanchez", helvetica, arial, sans-serif;
|
||||
margin: 24px 0 0 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font: normal 18px "Sanchez", helvetica, arial, sans-serif;
|
||||
margin: 24px 0 0 0;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
color: hsl(195, 90%, 50%);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
a {
|
||||
color: hsl(195, 80%, 40%);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: hsl(195, 70%, 40%);
|
||||
}
|
||||
|
||||
.header-anchor {
|
||||
display: none;
|
||||
}
|
||||
|
||||
h2:hover > .header-anchor, h3:hover > .header-anchor {
|
||||
display: inline;
|
||||
color: hsl(195, 30%, 90%);
|
||||
}
|
||||
|
||||
h2:hover > .header-anchor:hover, h3:hover > .header-anchor:hover {
|
||||
color: hsl(195, 70%, 40%);
|
||||
}
|
||||
|
||||
p, li {
|
||||
font: 17px/26px "Source Sans Pro", georgia, serif;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
p + p {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
code, pre, tt {
|
||||
color: hsl(195, 20%, 40%);
|
||||
font: 14px "Source Code Pro", Menlo, Monaco, Consolas, monospace;
|
||||
background: hsl(195, 20%, 95%);
|
||||
border-bottom: solid 2px hsl(195, 30%, 91%);
|
||||
}
|
||||
|
||||
code, pre {
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 1px 3px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 12px 0;
|
||||
line-height: 20px;
|
||||
padding: 11px;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: hsl(195, 50%, 20%);
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
border-bottom: solid 2px hsl(330, 100%, 50%);
|
||||
box-shadow: 0 10px 30px -10px hsl(195, 55%, 10%) inset;
|
||||
}
|
||||
|
||||
.page {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 840px;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
float: left;
|
||||
font: 36px "Sanchez", helvetica, arial, sans-serif;
|
||||
color: #fff;
|
||||
padding-top: 25px;
|
||||
margin: 0;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.header h1 a {
|
||||
color: #fff;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.header a:hover {
|
||||
color: hsl(330, 100%, 50%);
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.header h2 {
|
||||
float: right;
|
||||
margin: 0;
|
||||
padding: 44px 0 0 0;
|
||||
font: 17px "Source Sans Pro", helvetica, arial, sans-serif;
|
||||
font-weight: 300;
|
||||
letter-spacing: 1px;
|
||||
color: hsl(195, 50%, 50%);
|
||||
}
|
||||
|
||||
.content {
|
||||
display: inline-block;
|
||||
width: 620px;
|
||||
}
|
||||
|
||||
.nav {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 140px;
|
||||
padding: 20px 20px 0 20px;
|
||||
background: hsl(195, 40%, 95%);
|
||||
border-bottom-left-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
border-bottom: solid 2px hsl(195, 50%, 90%);
|
||||
}
|
||||
|
||||
.nav h2 {
|
||||
font: normal 18px "Sanchez", helvetica, arial, sans-serif;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nav ul {
|
||||
padding: 0;
|
||||
margin: 6px 0 20px 0;
|
||||
}
|
||||
|
||||
.nav li {
|
||||
font: 15px "Source Sans Pro", helvetica, arial, sans-serif;
|
||||
font-weight: 400;
|
||||
list-style-type: none;
|
||||
margin: 0 0 6px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
color: #888;
|
||||
font: italic 14px "Source Sans Pro", georgia, serif;
|
||||
text-align: center;
|
||||
margin: 30px 0 40px 0;
|
||||
}
|
||||
|
||||
/* syntax highlighting */
|
||||
|
||||
.codehilite pre span.c1 { color: hsl(195, 10%, 60%); } /* line comment */
|
||||
.codehilite pre span.cm { color: hsl(195, 10%, 60%); } /* block comment */
|
||||
.codehilite pre span.vg { color: #5d3a85; } /* global variable */
|
||||
.codehilite pre span.vi { color: #784bab; } /* instance variable */
|
||||
.codehilite pre span.k { color: hsl(195, 80%, 40%); } /* keyword message */
|
||||
.codehilite pre span.p { color: #777; } /* punctuation ()[]{} */
|
||||
.codehilite pre span.s { color: hsl(330, 60%, 55%); } /* string */
|
||||
.codehilite pre span.se { color: hsl(30, 90%, 45%); } /* string escape */
|
||||
.codehilite pre span.nb { color: #30a138; } /* built-in name: self undefined */
|
||||
.codehilite pre span.o { color: hsl(195, 100%, 35%); } /* operator */
|
||||
.codehilite pre span.kd { color: hsl(195, 100%, 45%); } /* keyword decl */
|
||||
.codehilite pre span.nv { color: #24a36a; } /* argument name */
|
||||
.codehilite pre span.ow { color: #30a186; } /* user-defined operator */
|
||||
.codehilite pre span.mi { } /* number */
|
||||
.codehilite pre span.n { } /* name */
|
||||
190
doc/site/style.scss
Normal file
190
doc/site/style.scss
Normal file
@ -0,0 +1,190 @@
|
||||
//$header: "Sanchez", helvetica, arial, sans-serif;
|
||||
$header: "Dosis", helvetica, arial, sans-serif;
|
||||
$body: "Source Sans Pro", georgia, serif;
|
||||
$code: "Source Code Pro", Menlo, Monaco, Consolas, monospace;
|
||||
|
||||
// roboto: boring
|
||||
// dosis: nice, "wren" looks good, bit nerdy
|
||||
// mont: nice and wide
|
||||
// raleway: great w
|
||||
|
||||
$p: 195;
|
||||
|
||||
$light-gray: hsl($p, 20%, 80%);
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body, code, h1, h2, h3, p, pre, tt {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font: 36px/40px $header;
|
||||
margin: 50px 0 0 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font: normal 24px $header;
|
||||
margin: 24px 0 0 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font: normal 18px $header;
|
||||
margin: 24px 0 0 0;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
color: hsl($p, 90%, 50%);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
a {
|
||||
color: hsl($p, 80%, 40%);
|
||||
text-decoration: none;
|
||||
transition: color 0.3s, text-shadow 0.3s;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: hsl(330, 100%, 50%);
|
||||
text-shadow: 0 0 6px hsla(330, 100%, 50%, 0.2);
|
||||
}
|
||||
|
||||
.header-anchor {
|
||||
display: none;
|
||||
}
|
||||
|
||||
h2:hover > .header-anchor, h3:hover > .header-anchor {
|
||||
display: inline;
|
||||
color: hsl($p, 30%, 90%);
|
||||
}
|
||||
|
||||
h2:hover > .header-anchor:hover, h3:hover > .header-anchor:hover {
|
||||
color: hsl($p, 70%, 40%);
|
||||
text-shadow: 0 0 6px hsla($p, 100%, 50%, 0.2);
|
||||
}
|
||||
|
||||
p, li {
|
||||
font: 17px/26px $body;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
p + p {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
code, pre {
|
||||
color: hsl($p, 20%, 40%);
|
||||
font: 14px $code;
|
||||
background: hsl($p, 20%, 97%);
|
||||
border-radius: 4px;
|
||||
|
||||
border: solid 1px hsl($p, 30%, 92%);
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 1px 3px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 12px 0;
|
||||
line-height: 20px;
|
||||
padding: 11px;
|
||||
}
|
||||
|
||||
.page {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 840px;
|
||||
}
|
||||
|
||||
.header {
|
||||
position: absolute;
|
||||
width: 840px;
|
||||
height: 100px;
|
||||
border-bottom: solid 1px hsl($p, 20%, 93%);
|
||||
|
||||
h1 {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
font: 56px $header;
|
||||
font-weight: 300;
|
||||
margin: 0;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 7px;
|
||||
color: $light-gray;
|
||||
font: 18px $header;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: inline-block;
|
||||
margin-top: 100px;
|
||||
width: 620px;
|
||||
margin-left: 220px;
|
||||
}
|
||||
|
||||
.nav {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 140px;
|
||||
margin-top: 201px;
|
||||
|
||||
h2 {
|
||||
color: $light-gray;
|
||||
font: normal 18px $header;
|
||||
margin: 0;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0;
|
||||
margin: 6px 0 20px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font: 15px $body;
|
||||
font-weight: 400;
|
||||
list-style-type: none;
|
||||
margin: 0 0 6px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
color: $light-gray;
|
||||
font: italic 14px $body;
|
||||
text-align: center;
|
||||
margin: 30px 0 40px 0;
|
||||
}
|
||||
|
||||
// Syntax highlighting.
|
||||
.codehilite pre span.c1 { color: hsl($p, 20%, 65%); } /* line comment */
|
||||
.codehilite pre span.cm { color: hsl($p, 20%, 65%); } /* block comment */
|
||||
.codehilite pre span.vg { color: #5d3a85; } /* global variable */
|
||||
.codehilite pre span.vi { color: #784bab; } /* instance variable */
|
||||
.codehilite pre span.k { color: hsl($p, 80%, 40%); } /* keyword message */
|
||||
.codehilite pre span.p { color: #777; } /* punctuation ()[]{} */
|
||||
.codehilite pre span.s { color: hsl(330, 60%, 55%); } /* string */
|
||||
.codehilite pre span.se { color: hsl(30, 90%, 45%); } /* string escape */
|
||||
.codehilite pre span.nb { color: #30a138; } /* built-in name: self undefined */
|
||||
.codehilite pre span.o { color: hsl($p, 100%, 35%); } /* operator */
|
||||
.codehilite pre span.kd { color: hsl($p, 100%, 45%); } /* keyword decl */
|
||||
.codehilite pre span.nv { color: #24a36a; } /* argument name */
|
||||
.codehilite pre span.ow { color: #30a186; } /* user-defined operator */
|
||||
.codehilite pre span.mi { } /* number */
|
||||
.codehilite pre span.n { } /* name */
|
||||
@ -4,25 +4,23 @@
|
||||
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
|
||||
<title>{title} – Wren</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
<link href='http://fonts.googleapis.com/css?family=Sanchez:400|Source+Sans+Pro:300,400,700,400italic,700italic|Source+Code+Pro:300,400' rel='stylesheet' type='text/css'>
|
||||
<link href='http://fonts.googleapis.com/css?family=Dosis:300,400|Source+Sans+Pro:300,400,700,400italic,700italic|Source+Code+Pro:300,400' rel='stylesheet' type='text/css'>
|
||||
</head>
|
||||
<body id="top">
|
||||
<a href="https://github.com/munificent/wren">
|
||||
<img style="position: absolute; top: 0; right: 0; border: 0; z-index: 100;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" alt="Fork me on GitHub">
|
||||
</a>
|
||||
<div class="header">
|
||||
<div class="page">
|
||||
<h1><a href="index.html">wren</a></h1>
|
||||
<h2>a minimal class-based scripting language</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page">
|
||||
<div class="header">
|
||||
<h1><a href="index.html">wren</a></h1>
|
||||
<h2>a classy little scripting language</h2>
|
||||
</div>
|
||||
<div class="nav">
|
||||
<h2>Welcome</h2>
|
||||
<h2>welcome</h2>
|
||||
<ul>
|
||||
<li>Getting Started</li>
|
||||
</ul>
|
||||
<h2>Language</h2>
|
||||
<h2>language</h2>
|
||||
<ul>
|
||||
<li><a href="syntax.html">Syntax</a></li>
|
||||
<li><a href="method-calls.html">Method calls</a></li>
|
||||
@ -30,7 +28,7 @@
|
||||
<li><a href="branching.html">Branching</a></li>
|
||||
<li><a href="looping.html">Looping</a></li>
|
||||
</ul>
|
||||
<h2>Types</h2>
|
||||
<h2>types</h2>
|
||||
<ul>
|
||||
<li><a href="values.html">Values</a></li>
|
||||
<li><a href="classes.html">Classes</a></li>
|
||||
@ -39,23 +37,23 @@
|
||||
<li><a href="lists.html">Lists</a></li>
|
||||
<li><a href="maps.html">Maps</a></li>
|
||||
</ul>
|
||||
<h2>Usage</h2>
|
||||
<h2>usage</h2>
|
||||
<ul>
|
||||
<li>Concurrency</li>
|
||||
<li>Error handling</li>
|
||||
<li>Standalone</li>
|
||||
<li>Embedding</li>
|
||||
</ul>
|
||||
<h2>Other</h2>
|
||||
<h2>other</h2>
|
||||
<ul>
|
||||
<li><a href="qa.html">Q & A</a></li>
|
||||
<li><a href="performance.html">Performance</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h1>{title}</h1>
|
||||
{html}
|
||||
<p class="footer">Last modified on {mod}. By Bob Nystrom.</p>
|
||||
</div>
|
||||
<h1>{title}</h1>
|
||||
{html}
|
||||
<p class="footer">Last modified on {mod}. By Bob Nystrom.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -4,6 +4,7 @@ import glob
|
||||
import markdown
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from datetime import datetime
|
||||
@ -78,19 +79,26 @@ def format_file(path, skip_up_to_date):
|
||||
print "converted", basename
|
||||
|
||||
|
||||
def check_sass():
|
||||
source_mod = os.path.getmtime('doc/site/style.scss')
|
||||
|
||||
dest_mod = 0
|
||||
if os.path.exists('build/docs/style.css'):
|
||||
dest_mod = os.path.getmtime('build/docs/style.css')
|
||||
|
||||
if source_mod < dest_mod:
|
||||
return
|
||||
|
||||
subprocess.call(['sass', 'doc/site/style.scss', 'build/docs/style.css'])
|
||||
print "built css"
|
||||
|
||||
|
||||
def format_files(skip_up_to_date):
|
||||
check_sass()
|
||||
|
||||
for f in glob.iglob("doc/site/*.markdown"):
|
||||
format_file(f, skip_up_to_date)
|
||||
|
||||
# Copy the CSS file.
|
||||
css_in = "doc/site/style.css"
|
||||
css_out = "build/docs/style.css"
|
||||
if skip_up_to_date and is_up_to_date(css_in, css_out):
|
||||
pass
|
||||
else:
|
||||
shutil.copyfile(css_in, css_out)
|
||||
print "copied css"
|
||||
|
||||
|
||||
# Clean the output directory.
|
||||
if not os.path.exists("build"):
|
||||
|
||||
Reference in New Issue
Block a user