1
0
forked from Mirror/wren

Redo site design.

This commit is contained in:
Bob Nystrom
2014-04-05 15:39:02 -07:00
parent bffb0e5d93
commit 28021dc63e
8 changed files with 228 additions and 213 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
# Intermediate files directory.
build/
build_xcode/
.sass-cache/
# Built applications.
wren

View File

@ -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

View File

@ -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?

View File

@ -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?

View File

@ -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
View 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 */

View File

@ -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 &amp; 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>

View File

@ -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"):