diff --git a/.gitignore b/.gitignore index 921d561e..540035ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Intermediate files directory. build/ build_xcode/ +.sass-cache/ # Built applications. wren diff --git a/Makefile b/Makefile index 93e4093e..4b7102cb 100644 --- a/Makefile +++ b/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 diff --git a/doc/site/performance.markdown b/doc/site/performance.markdown index 6446268c..149bdd78 100644 --- a/doc/site/performance.markdown +++ b/doc/site/performance.markdown @@ -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? diff --git a/doc/site/qa.markdown b/doc/site/qa.markdown index 074bc535..fcf06d49 100644 --- a/doc/site/qa.markdown +++ b/doc/site/qa.markdown @@ -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? diff --git a/doc/site/style.css b/doc/site/style.css deleted file mode 100644 index f2f9cfd9..00000000 --- a/doc/site/style.css +++ /dev/null @@ -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 */ diff --git a/doc/site/style.scss b/doc/site/style.scss new file mode 100644 index 00000000..449e58fa --- /dev/null +++ b/doc/site/style.scss @@ -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 */ diff --git a/doc/site/template.html b/doc/site/template.html index 0e6f52fc..9fb23b66 100644 --- a/doc/site/template.html +++ b/doc/site/template.html @@ -4,25 +4,23 @@ {title} – Wren - + Fork me on GitHub -
-
-

wren

-

a minimal class-based scripting language

-
-
+
+

wren

+

a classy little scripting language

+
-

{title}

-{html} - -
+

{title}

+ {html} + +
\ No newline at end of file diff --git a/script/generate_docs.py b/script/generate_docs.py index 70cb9419..0bebfe74 100755 --- a/script/generate_docs.py +++ b/script/generate_docs.py @@ -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"):