Merge pull request #223 from ThakeeNathees/docs-change

documentations are refactored
This commit is contained in:
Thakee Nathees 2022-05-07 17:54:32 +05:30 committed by GitHub
commit b908f85338
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 883 additions and 2591 deletions

View File

@ -32,7 +32,7 @@ DEF(stdMathCeil,
} }
DEF(stdMathPow, DEF(stdMathPow,
"pow(value:num) -> num\n") { "pow(a:num, b:num) -> num\n") {
double num, ex; double num, ex;
if (!pkValidateSlotNumber(vm, 1, &num)) return; if (!pkValidateSlotNumber(vm, 1, &num)) return;

0
docs/.nojekyll Normal file
View File

46
docs/404.html Normal file
View File

@ -0,0 +1,46 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap');
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Roboto Mono', monospace;
}
.middle {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.display {
text-align: center;
font-size: clamp(22px, 3vw, 60px);
}
.fn {
color:#2b6cb0;
}
.string {
color:#219321
}
</style>
<title>pocketlang</title>
</head>
<body>
<div class="middle">
<div class="display">
<span class="fn">print</span>(<span class="string">'Page under construction'</span>)
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,395 @@
# Language Manual
You can consider pocketlang's syntax as python without indentation. For block statements it uses the ruby way, 'end' keyword
to close a block, end a class, function etc. Most of the semantics are simillar to python and if you're know python it fairly
easier to grasp pocketlang.
## Hello World
```ruby
print('Hello World')
```
## Comments and White Spaces
Comments are marked with `#` and ends at the next new line character.
```ruby
# Beautiful is better than ugly.
# Explicit is better than implicit.
# Simple is better than complex.
# Complex is better than complicated.
```
Except for new lines all the white spaces are ignored. New lines are used to end a statement, every statement should
ends with a new line or semicollon.
## Code blocks
Code blocks are following the same rule of ruby. All the blocks are closed with the `end` keyword,
all blocks are stards with either a new line and an optional "block entering keyword". For a single line
block these keywords are must. `if` blocks starts with the `then`, for `while` and `for` loops they starts
with the `do` keyword.
```ruby
## The `do` keyword is a must here.
while cond do something() end
## The `do` keyword is a optional here.
for i in 0..10
print('$i')
end
## `then` is optional if new line is present.
if cond1 then
foo()
else if cond2
bar()
else
baz()
end
```
# Data Types
Pocketlang has 3 primitive types which are `null`, `boolean` and `number` all the number values are represented as
IEEE 754 double precision floats. `null`, `true`, `false` are their literals and number support binary, hex and scientific
literals `0b101001`, `0xc0ffee`, `3e8`.
There are a handfull number of reference types like String, Range, List, Map, Closure (which is the first class functions),
Fiber, etc. And you can define you own with the `class` keyword.
## String
String sin pocketlang can be either double quoted or single quoted. At the moment pocket lang only supported a limited
number of string escape characters and UTF8 is not supported. However it'll be implemented before the first release.
```ruby
"Hello there!"; 'I\'m a string.'
"I'm a multi
line string."
```
Additionally pocketlang strings by default support interpolation with the `$` symbol. For a single identifier
it can be just written without any enclosing brackets, and for a long expressions they should be inside curly
brackets. And they can be nested upto 8 depth.
```ruby
n = 25
print('sqrt($n) = ${sqrt(n)}')
```
## Range
A range value represent an interval, they can be created with the `..` operator between two whole numbers.
```ruby
for i in 0..10
print(i)
end
```
!> Unlike ruby we don't have a `...` operator and pocketlang Range objects are exclusive.
Exclusive ranges are more natural and more usefull when it comes to iterate over the length of something, thus
pocketlang's ranges are always exclusive. And having two operator for the same but slightly different operation is
a bit redundant in our humble openion.
## List
Lists are a collection of ordered objects. Each element can be indexed starting at 0. Internally a list is a
dynamically allocated variables buffer they'll grow or shrink as needed to store them.
```ruby
[ 'apples', true, 0..5 ]
[
[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
]
```
## Map
Maps are a collection of un ordered objects that stores the mapping of unique keys to the values. Internally it's
implemented as a has table and it require a value to be hashable for it to be a key. In pocketlang only primitive
types and immutable objects (`String` and `Range`) are hashable.
```ruby
{
12 : 34,
0..3 : [0, 1, 2],
'foo' : 'bar',
}
```
## Closure
Closure are the first class citizen of functions that can be created, assigned to variables, passed as an argument,
or returned from a function call. A closure can be created with the `fn` keyword, which will crate an
anonymous function and wraps itself around it.
```ruby
y = fn (x) return x * x end
```
Pocketlang support lexical scoping which allows the closure to capture an external local variable
out of it's own scope. They're more like lambda expressions in other langauges.
```ruby
def make_function(m, c)
return fn(x)
return m * x + c
end
end
```
?> Note that a call of form `f(fn ... end)` is a syntax sugar for `f fn ... end` where `f` is a function
or a method that takes a single literal function as argument, like Lua.
```ruby
5.times fn(i)
print(i)
end
```
## Fiber
Pocketlang support coroutines via [fibers](https://en.wikipedia.org/wiki/Fiber_(computer_science))
(light weight threads with cooperative multitask). A fiber object is a wrapper around a closure, contains
the execution state (simply the stack and the instruction pointer) of that closure, which can be run
and once yielded resumed.
```ruby
def foo()
print("Hello from fiber!")
end
fb = Fiber(foo)
fb.run()
```
When a function is yielded, it's state will be stored in the fiber it's belongs to and will return from
the function, to parent fiber it's running from (not the caller of the function). You can pass values
between fibers when they yield.
```ruby
def foo()
print('running')
yield()
print('resumed')
end
fb = Fiber(foo)
fb.run() # Prints 'running'.
print('before resumed')
fb.resume() # Prints 'resumed'.
```
Yield from the fiber with a value.
```ruby
def foo()
print('running')
yield(42) # Return 42.
print('resumed')
end
fb = Fiber(foo)
val = fb.run() # Prints 'running'.
print(val) # Prints 42.
fb.resume() # Prints 'resumed'.
```
Resume the fiber with a value.
```ruby
def foo()
print('running')
val = yield() # Resumed value.
print(val) # Prints 42.
print('resumed')
end
fb = Fiber(foo)
val = fb.run() # Prints 'running'.
fb.resume(42) # Resume with 42, Prints 'resumed'.
```
Once a fiber is done execution, trying to resume it will cause a runtime error. To check if the
fiber is finished check its attribute `is_done` and use the attribute `function` to get it's function,
which could be used to create a new fiber to "re-start" the fiber.
```ruby
fb = Fiber foo()
for i in 0..5
yield(i)
end
end
fb.run()
while not fb.is_done
fb.resume()
end
# Get the function from the fiber.
f = fb.get_func()
```
## Classes
Classes are the blueprint of objects, contains method definitions and behaviors for its instances.
The instance of a class method can be accessed with the `self` keyword.
```ruby
class Foo end
foo = Foo() ## Create a foo instance of Foo class.
```
To initialize an instance when it's constructed use `_init` method. Pocketlang instance attributes
are dynamic (means you can add a new field to an instance on the fly).
```ruby
class Foo
def _init(bar, baz)
self.bar = bar
end
end
foo = Foo('bar', 'baz')
```
To override an operator just use the operator symbol as the method name.
```ruby
class Vec2
def _init(x, y)
self.x = x; self.y = y
end
def _str
return "<${self.x}, ${self.y}>"
end
def + (other)
return Vec2(self.x + other.x,
self.y + other.y)
end
def += (other)
self.x += other.x
self.y += other.y
return self
end
def == (other)
return self.x == other.x and self.y == other.y
end
end
```
To distinguish unary operator with binary operator the `self` keyword should be used.
```ruby
class N
def _init(n)
self.n = n
end
def - (other) ## N(1) - N(2)
return N(self.n - other.n)
end
def -self () ## -N(1)
return N(-self.n)
end
end
```
All classes are ultimately inherit an abstract class named `Object` to inherit from any other class
use `is` keyword at the class definition. However you cannot inherit from the builtin class like
Number, Boolean, Null, String, List, ...
```ruby
class Shape # Implicitly inherit Object class
end
class Circle is Shape # Inherits the Shape class
end
```
To override a method just redefine the method in a subclass.
```ruby
class Shape
def area()
assert(false)
end
end
class Circle is Shape
def _init(r)
self.r = r
end
def area()
return math.PI * r ** 2
end
end
```
To call the a method on the super class use `super` keyword. If the method name is same as the current
method `super()` will do otherwise method name should be specified `super.method_name()`.
```ruby
class Rectangle is Shape
def _init(w, h)
self.w = w; self.h = h
end
def scale(fx, fy)
self.w *= fx
self.h *= fy
end
end
class Square is Rectangle
def _init(s)
super(s, s) ## Calls super._init(s, s)
end
def scale(x)
super(x, x)
end
def scale2(x, y)
super.scale(x, y)
end
end
```
## Importing Modules
A module is a collection of functions classes and global variables. Usually a single script file
will be compiled to a module. To import a module use `import` statement.
```ruby
import math # Import math module.
import lang, math # Import multiple modules.
from math import sin, tan # Import symbols from a module.
# Using alias to bind with a different name.
import math as foo
from lang import clock as now
# Import inside a directory
import foo.bar # Import module bar from foo directory
import baz # If baz is a directory it'll import baz/_init.pk
# I'll only search for foo relatievly.
import .foo # ./foo.pk or ./foo/_init.pk or ./foo.dll, ...
# ^ meaning parent directory relative to this script.
import ^^foo.bar.baz # ../../foo/bar/baz.pk
```
?> Note that star import `from foo import *` is not supported but may be in the future.

63
docs/README.md Normal file
View File

@ -0,0 +1,63 @@
<h1 class="text-center">
Pocketlang <sub>v0.1.0</sub>
</h1>
<p class="text-center">
Pocketlang is a lightweight & fast object oriented programming language designed for embedding and
scripting. Including the compiler, bytecode VM and runtime it's a <strong>standalone</strong> executable
which is less than <strong>300KB</strong> and the language itself can be compiled in less than
<strong>4s</strong> without any external dependencies.
</p>
<div class="center">
<a class="button" target="_blank" href="/try-online.html"> Try Online </a>
<a class="button" target="_blank" href="https://www.github.com/ThakeeNathees/pocketlang/"> GitHub </a>
</div>
<br>
Simplicity is the zen of pocketlang. The syntax is more of an executable pseudocode. Compiling the language
itself takes just a single gcc/msvc command. No configuration is required to embed it in another application.
pocket VM along with its compiler and standard runtime are a single executable that's less than 300KB. It's not
just small but much faster with memory efficient dynamic type system, self adjusting heap for garbage
collection, tail call optimization, single pass compilation etc, that makes it compete with main stream langages
like python, ruby, wren and lua. And more things that makes pocketlang a swiss knife of programmers.
## What it looks like
```ruby
# A recursive fibonacci function.
def fib(n)
if n < 2 then return n end
return fib(n-1) + fib(n-2)
end
# Prints all fibonacci from 0 to 10 exclusive.
for i in 0..10
print("fib($i) = ${fib(i)}")
end
```
## Features
- No setup. Single binary and your're good to go.
- REPL
- Object oriented
- Dynamic typing
- Concurrency
- Garbage collection
- Operator overloading
- First class functions
- Lexical scoping
- Embeddable
- Direct interop with C
- Highly optimized loops
- Tail call optimization
## Getting Started
Note that at the moment there isn't any releases and it's actively being developed. To get your hands
dirty clone the [source](https://www.github.com/ThakeeNathees/pocketlang/) and build it. Compiling
the language itself takes just a single gcc/msvc command. See [README](https://github.com/ThakeeNathees/pocketlang#readme)
for more detail.

29
docs/Reference/Math.md Normal file
View File

@ -0,0 +1,29 @@
# math
TODO: this page is incomplete.
#### math.floor
```ruby
floor(value:num) -> num
```
#### math.ceil
```ruby
ceil(value:num) -> num
```
#### math.pow
```ruby
pow(a:num, b:num) -> num
```
#### math.sqrt
```ruby
sqrt(value:num) -> num
```
#### math.abs
```ruby
abs(value:num) -> num
```

23
docs/Reference/Path.md Normal file
View File

@ -0,0 +1,23 @@
# path
TODO: this page is incomplete.
#### path.getcwd
```ruby
getcwd() -> str
```
#### path.abspath
```ruby
abspath(path:str) -> str
```
#### path.relpath
```ruby
relpath(path:str) -> str
```
#### path.join
```ruby
join(...path:str) -> str
```

View File

@ -1,63 +0,0 @@
// Language features.
- Utf8 support.
- Make assert a keyword and disable it on release build.
// To implement.
- implement 'lang.getMaxCallDepth()' (default=1000 like python) and
setMaxCallDepth(val) to change stack size at runtime. (at: pushCallFrame())
- change or add => to_string() to value.as_string
and add as_repr, as_bool.
- Implement gdb like debugger (add color print for readability).
- Complete all the TODO; macros.
- implement MAX_ARGC checks (would cause a buffer overflow if not)
when compiling and calling a function (also in fibers).
// Low priority.
- Ignore line with '\' character.
- Make it possible to override function names.
- To do so the functions and global variables should be in the same
buffer as the property of the script.
- Union tagging alter in var.
// Add more.
- Single header for embedding (script in pk, require file IO).
- Complete core methods.
- Complete var methods.
- Complete core functions.
- Complete builtin operators.
- Complete opcodes.
- Complete core libs.
- Complete the docs.
- More Tests.
// Enhancements
- Write a custom hex() function to cast uint64_t to hex
string (currently our max is uint32_t) and for binary
(C doesn't have a sprintf("%b", num) for us.
- Ensure that the bitwise operation result `a << b` can be fit
into a double value before casting it to one. and we're allowing
the integer overflow when shifting.
// Bugs.
It's at pre-alpha and every thing is left to
implement, and nothing would be work as expected.
- f = func print() end; print(f) # semicolon should be there.
def f() print() end print(f) # semicolon should be there.
make it okay to use semicolon freely like new lines.
- REPL error message should be the first one (not the last).
>>> def f()
... _f = func()
... _f() // _f not defined (no closure).
... end
Error: Expected an expression // expected Name '_f' not defined.
Update: The above code just terminates in repl without printing any
error messages.

8
docs/_sidebar.md Normal file
View File

@ -0,0 +1,8 @@
* Getting Started
* [Home](/)
* [Language Manual](/GettingStarted/LanguageManual.md)
* Library Reference
* [math](/Reference/Math.md)
* [path](/Reference/Path.md)

View File

@ -1,288 +0,0 @@
## Make sure you have installed markdown library (pip install Markdown)
## and the python version is 3.6+.
import os, sys, re, json, html
from os.path import abspath, dirname, exists, isdir, join
from shutil import copyfile, copytree, rmtree
from markdown import markdown
## FIXME: the below version string is hardcoded.
POCKETLANG_VERSION = "v0.1.0"
## Page contnet will be ordered as the below list. Each entry in the DOC_PAGES
## is called a section (which will be it's own folder) and each entry in the
## section is a page (which will be in it's own file). Additionally each page
## has it's own topic that'll be generated as h2 tags.
##
## A generated context of the function collect_doc_pages() will be in the form
## of :- { section : [ page : (html, [topic]) ] }
## where html is the html version of the markdown file.
##
DOC_PAGES = {
"Reference" : [
"Getting-Started",
"Cheat-Sheet",
"Build-From-Source",
"Installation",
],
"Api-Docs" : [
"Fiber",
"Module",
],
}
## Site pages are template html files in the "./templates/" folder, which will
## generated to the build directory.
SITE_PAGES = [
"index.html",
"try-online.html",
]
## Display pocketlang syntax for the home page.
WHAT_IT_LOOKS_LIKE = '''
# Python like import statement.
from lang import clock as now
# A recursive fibonacci function.
def fib(n)
if n < 2 then return n end
return fib(n-1) + fib(n-2)
end
# Prints all fibonacci from 0 to 10 exclusive.
for i in 0..10
print(fib(i))
end
'''
## Display features in the home page.
POCKET_FEATURES = {
"Concurrent" : {
"icon" : "{{ STATIC_DIR }}img/concurrent.svg",
"desc" : "Pocketlang's fibers (lightweight threads) allows you to write "
"parallel tasks easily, without worrying about thread safety.",
"link" : "{{TODO}}"
},
"Embeddible" : {
"icon" : "{{ STATIC_DIR }}img/gear.svg",
"desc" : "You can use PKVM as any other libraries in your application. "
"It's specifically designed to be embedded in other programs.",
"link" : "{{TODO}}"
},
"Garbage Collected" : {
"icon" : "{{ STATIC_DIR }}img/gc.svg",
"desc" : "With the pocketlang's garbage collector you can write code "
"without worrying about memory management.",
"link" : "{{TODO}}"
},
"REPL" : {
"icon" : "{{ STATIC_DIR }}img/repl.svg",
"desc" : "The interactive prompt of pocketlang will makes it easier to "
"test and play with it on the command line.",
"link" : "{{TODO}}"
},
}
## The absolute path of this file's directory, when run as a script.
## This file is not intended to be included in other files at the moment.
THIS_PATH = abspath(dirname(__file__))
BUILD_DIR = join(THIS_PATH, "build")
STATIC_DIR = join(THIS_PATH, "static")
MARKDOWN_DIR = join(THIS_PATH, "markdown")
TEMPLATE_PATH = join(THIS_PATH, 'templates/docs.html')
DOCS_URL_PATH = f"docs/{POCKETLANG_VERSION}/" ## Html generated at docs/* path.
def main():
## Getting things ready.
check_wasm()
clean()
make_build_dir()
## Site pages generation.
gen_site_pages()
## Documentation pages generation.
context = collect_doc_pages()
gen_doc_pages(context)
print("Docs generated successfully")
## INTERNAL ###################################################################
## Opens the file at the path read it and return it's content.
def read(path):
with open(path, 'r') as fp:
return fp.read()
def check_wasm():
if not exists(join(STATIC_DIR, 'wasm/')):
print("[Warning] pocketlang web assembly files weren't generated.")
print(" to compile, see docs/wasm/README.md")
## Remove all generated files at the build path.
def clean():
REMOVE_IGNORE =('.git',)
if not exists(BUILD_DIR): return
for item in os.listdir(BUILD_DIR):
if item in REMOVE_IGNORE: continue
item = join(BUILD_DIR, item)
if isdir(item): rmtree(item)
else: os.remove(item)
## Generate necessary folder and files to the build dir, copy static folder and
## prepare for the generation.
def make_build_dir():
## Create '.nojekyll' for github pages.
if not exists(BUILD_DIR): os.makedirs(BUILD_DIR)
open(join(BUILD_DIR, '.nojekyll'), 'w').close()
copytree(STATIC_DIR, join(BUILD_DIR, "static"))
def generate_features():
gen = ""; indentation = ' ' * 4
def write(html_line):
nonlocal gen; nonlocal indentation
gen += indentation + html_line + '\n'
for feature_name in POCKET_FEATURES:
feature = POCKET_FEATURES[feature_name]
write('<div class="feature">')
write(' <div class="feature-logo">')
write(f' <img src="{feature["icon"]}">')
write(' </div>')
write(f' <h2>{feature_name}</h2>')
write(f' <p>{feature["desc"]}</p>')
write(f' <a class="link" href="{feature["link"]}">Learn more</a>')
write('</div>')
return gen
def gen_site_pages():
for site_page in SITE_PAGES:
template = read(join(THIS_PATH, f"templates/{site_page}"))
if site_page == "index.html":
code_example = html.escape(WHAT_IT_LOOKS_LIKE)
template = template.replace("{{ WHAT_IT_LOOKS_LIKE }}", code_example)
template = template.replace("{{ POCKET_FEATURES }}", generate_features())
template = template.replace("{{ POCKETLANG_VERSION }}", POCKETLANG_VERSION)
template = template.replace("{{ STATIC_DIR }}", "./static/")
template = template.replace("{{ DOCS_URL }}", DOCS_URL_PATH)
with open(join(BUILD_DIR, site_page), 'w') as fp:
fp.write(template)
## FIXME: wirte a better md -> html compiler (or use some libraries).
## Compile the markdown files to html. and return the a tuple of (html, topics)
## where topics are h2 tag headers inside the markdown files.(h1 tag is
## reserved for the page heading).
def compile_markdown(md):
topics = []
md_new = ""
in_code = False
for line in md.splitlines():
stripped_line = line.strip()
## Get topics.
if stripped_line.startswith("## "):
topic = stripped_line[3:]
topics.append(topic)
md_new += f'<h2 class="topic-title">{topic} <a href="#{topic}" ' +\
f'id="{topic}" class="anchor">#</a></h2>\n'
## Parse codeblocks (markdown library doesn't support this extended
## markdown syntax).
elif not in_code and stripped_line.startswith("```"):
## Expected a lang name and EOL.
lang = stripped_line[3:]
md_new += f'<pre><code class="highlight {lang}">\n'
in_code = True
## End of codeblock.
elif in_code and stripped_line.startswith('```'):
md_new += '</code></pre>\n'
in_code = False
else:
if in_code: line = html.escape(line)
md_new += line + "\n"
return markdown(md_new), topics
## Collect all markdown and generate the context (context is mentioned at the
## top of the script).
def collect_doc_pages():
context = dict()
for section in DOC_PAGES:
context[section] = dict()
for file_name in DOC_PAGES[section]:
md = read(join(MARKDOWN_DIR, section, file_name + '.md'))
context[section][file_name] = compile_markdown(md)
return context
## Generate navigation tree html tags with the tree information defined at the
## markdown/tree.json file (since python 3.6 dicionaries are ordered we're not
## using the OrderedDict here).
def generate_navtree(context):
gen = ""; indentation = ' ' * 4
def write(html_line):
nonlocal gen; nonlocal indentation
gen += indentation + html_line + '\n'
for section in context:
write('<li>')
write(' <div class="nav-section">')
write(' <p> %s </p>' % section.replace('-', ' '))
write(' <svg class="collapse-arrow" role="img" class="opacity-60" viewBox="0 0 16 16" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M12.78 6.22a.75.75 0 010 1.06l-4.25 4.25a.75.75 0 01-1.06 0L3.22 7.28a.75.75 0 011.06-1.06L8 9.94l3.72-3.72a.75.75 0 011.06 0z"></path></svg>')
write(' </div>')
write(' <ul class="nav-topics">')
for page in context[section]:
write(' <li><a href="%s"> %s </a></li>' % (
f"../{section}/{page}.html",
page.replace('-', ' ')))
write(' </ul>')
write('</li>')
return gen
## Generate table of content entries for the page.
def generate_toc_entries(topics):
gen = ""
for topic in topics:
gen += f'<li><a class="link" href="#{topic}">'
gen += f'{topic.replace("-", " ")}'
gen += '</a></li>\n'
return gen
## Build the template page with the generated context.
def gen_doc_pages(context):
navtree = generate_navtree(context)
template = read(TEMPLATE_PATH)
template = template.replace("{{ NAVIGATION_TREE }}", navtree)
template = template.replace("{{ LOGO_WHITE }}",
read(join(STATIC_DIR, "img/pocketlang.svg")))
template = template.replace("{{ URL_POCKET_HOME }}", "../../../index.html")
for section in context:
section_dir = join(BUILD_DIR, DOCS_URL_PATH, section)
os.makedirs(section_dir)
for page in context[section]:
content_html, topics = context[section][page]
toc_entries = generate_toc_entries(topics)
html = template ## "copy" the template string for the page.
html = html.replace("{{ PAGE_CONTENT }}", content_html)
html = html.replace("{{ PAGE_TITLE }}", page.replace('-', ' '))
html = html.replace("{{ TOC_ENTRIES }}", toc_entries)
html = html.replace("{{ STATIC_DIR }}", '../../../static/')
with open(join(section_dir, page + '.html'), 'w') as fp:
fp.write(html)
if __name__ == "__main__":
main()

66
docs/index.html Normal file
View File

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Pocketlag Docs</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="description" content="Description">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<link class="theme-light" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple.css" disabled>
<link class="theme-light" rel="stylesheet" href="static/highlight.js/stackoverflow-light.min.css" disabled>
<link class="theme-dark" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple-dark.css">
<link class="theme-dark" rel="stylesheet" href="static/highlight.js/github-dark-dimmed.min.css">
<link rel="stylesheet" href="static/style.css">
</head>
<body>
<div id="app"></div>
<script src="static/highlight.js/highlight.min.js"></script>
<script src="static/main.js"></script>
<script>
window.$docsify = {
name: 'pocketlang docs',
repo: 'https://www.github.com/ThakeeNathees/pocketlang/',
loadSidebar: true,
search: {
depth : 3,
noData : 'No results!',
placeholder : 'Search...',
},
themeable: {
readyTransition : true,
responsiveTables: true,
},
plugins: [
function(hook, vm) {
hook.doneEach(function() {
document.querySelectorAll('pre code').forEach(function(el) {
let pre = el.parentElement;
if (pre.getAttribute('data-lang') == 'ruby') {
pre.setAttribute('data-lang', 'pocket');
}
hljs.highlightElement(el);
});
});
hook.ready(function() {
onDocsifyReady();
});
}
],
}
</script>
<!-- Docsify v4 -->
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
<script src="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/js/docsify-themeable.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
</body>
</html>

View File

@ -1,96 +0,0 @@
Pocketlang support coroutines via [fibers](https://en.wikipedia.org/wiki/Fiber_(computer_science))
(light weight threads with cooperative multitask). A fiber object is a wrapper
around a function, contains the execution state (simply the stack and the
instruction pointer) for that function, which can be run and once yielded
resumed.
```ruby
import Fiber
def fn(h, w)
print(h, w)
end
fb = Fiber.new(fn) # Create a fiber.
Fiber.run(fb, 'hello', 'world') # Run the fiber.
```
## Yielding
When a function is yielded, it's state will be stored in the fiber it's
belongs to and will return from the function, to parent fiber it's running
from (not the caller of the function). And you can pass values between
fibers when they yield.
```ruby
import Fiber
def fn()
print('running')
yield()
print('resumed')
end
fb = Fiber.new(fn)
Fiber.run(fb) # Prints 'running'.
print('before resumed')
Fiber.resume(fb) # Prints 'resumed'.
```
Yield from the fiber with a value.
```ruby
import Fiber
def fn()
print('running')
yield(42) # Return 42.
print('resumed')
end
fb = Fiber.new(fn)
val = Fiber.run(fb) # Prints 'running'.
print(val) # Prints 42.
Fiber.resume(fb) # Prints 'resumed'.
```
Resume the fiber with a value.
```ruby
import Fiber
def fn()
print('running')
val = yield() # Resumed value.
print(val) # Prints 42.
print('resumed')
end
fb = Fiber.new(fn)
val = Fiber.run(fb) # Prints 'running'.
Fiber.resume(fb, 42) # Resume with 42, Prints 'resumed'.
```
Once a fiber is done execution, trying to resume it will cause a runtime
error. To check if the fiber is finished check its attribute
`is_done` and use the attribute `function` to get it's function,
which could be used to create a new fiber to "re-start" the fiber.
```ruby
import Fiber
Fiber.run(fb = Fiber.new(
func()
for i in 0..5 do
yield(i)
end
end))
while not fb.is_done
Fiber.resume(fb)
end
# Get the function from the fiber.
fn = Fiber.get_func(fb)
```

View File

@ -1,80 +0,0 @@
Each source file in pocketlang itself is a module that can be imported in another module, which makes it easier to split and share the project. There are two major kinds of modules in pocketlang. First one is core modules which are builtin to the VM and the second one is the local modules where it's a written script file you'll import it with the path of it.
## Importing a core module
The import statement of the pocketlang is highly inspired from python's import syntax. Here how it looks like.
```ruby
# To import a core module.
import lang
# Import multiple modules.
import lang, math
# Import functions from a module.
from lang import write, gc
# Using alias to bind with a different name.
import math as foo
from lang import clock as bar
# Import everything from a module.
from math import *
```
## Importing a local module
Importing a local module is same as importing a core module but instead of using the module name, you have to use it's path (either relative or absolute).
```ruby
# To import a local script with relative path.
import "foo.pk"
import "foo/bar.pk"
# Same rules with multiple imports and aliasing.
import 'foo.pk' as foo, '/bar.pk' as bar
from '../baz.pk' import *
```
If the local scripts have defined a module name, they'll imported and bound with it's module name if not they've imported with an alias. If the local script don't have a module name and imported without an alias, every symbols (global variables, and functions) will be imported and that's similar to import all statement.
```ruby
# 'foo.pk' isn't defined a module name.
import 'foo.pk'
fn() ## The function imported from 'foo.pk'
# We can use alias as a namespace if it doesn't have one.
import 'foo.pk' as foo
foo.fn()
# 'bar.pk' is defined with a module name 'bar'.
# It'll be imported and bound as variable bar.
import 'bar.pk'
bar.fn()
```
## The module keyword.
We can define a name to a module with the `module` keyword. The name will become the namespace for that module's functions and global variables when importing it.
```ruby
# 'foo.pk'
module foo
```
Note that the module name must be the first statement of the script and declared only once.
```ruby
# 'bar.pk'
module bar
fn = func print('hello') end
# 'foo.pk'
import './bar.pk'
bar.fn() ## prints 'hello'
```

View File

@ -1,40 +0,0 @@
Pocketlang can be build from source easily without any dependencies, or
additional requirements except for a c99 compatible compiler. It can be
compiled with the following command.
## GCC / MinGw / Clang (alias with gcc)
```
gcc -o pocket cli/*.c src/*.c -Isrc/include -lm
```
## MSVC
```
cl /Fepocket cli/*.c src/*.c /Isrc/include && rm *.obj
```
## Makefile
```
make
```
To run the make file on windows with `mingw`, you require the GNU `make` tool which you can get
from [msys2](https://www.msys2.org/) or [cygwin](https://www.cygwin.com/).
## Windows batch script
```
build
```
You don't have to run the script from a Visual Studio .NET developer command prompt, It'll search
for the MSVS installation path and setup the build environment.
## For other compiler/IDE
1. Create an empty project file / makefile.
2. Add all C files in the src directory.
3. Add all C files in the cli directory (**NOT** recursively).
4. Add `src/include` to include path.
5. Compile.
If you weren't able to compile it, please report us by [opening an issue](https://github.com/ThakeeNathees/pocketlang/issues/new).

View File

@ -1,104 +0,0 @@
```ruby
# This is a comment.
x = 0 # Creating a variable.
# In pocketlang statements should end with a new line
# or a semicolon. White space characters except for new
# lines are ignored in pocketlang.
a = 1; b = 2;
# Data types.
# -----------
null # A null type.
true; false # Booleans.
42; 3.14 # Numbers.
0..10; 10..0 # Range (0..10 = 0 <= r < 10).
"hello"; 'world' # Strings (support multiline).
[42, 'foo', null] # Lists.
{ 'Key':'value' } # Maps.
func(x) return x*x end # Lambda/literal functions.
# Control flow.
# -------------
# If condition.
if x == 'foo'
print('bar')
elsif x == 'bar'
print('baz')
end
# In a single line (should add 'then' keyword).
if x == 'foo' then print('bar') end
# For loops, here 'do' keyword is optional if we have a
# newline after the sequence (like 'then' in if statements).
for i in 0..10 do
print(i)
end
# While statement.
while x > 0 do print(x -= 1) end
# In pocketlang variable's lifetime are scope based.
if true then
local = null
end
#print(local) # Error: Name 'local' is not defined.
# Functions.
#-----------
def add(a, b)
return a + b
end
# Functions can be assigned to a variable.
fn = func(x) return x*x end
# Functions can be passed as an argument and can be returned.
def call(fn, x)
fn(x)
return func print('foo') end
end
# Classes
#--------
class _Vector
x = 0; y = 0
end
def Vector(x, y)
ret = _Vector()
ret.x = x; ret.y = y
return ret
end
def vecAdd(v1, v2)
return Vector(v1.x + v2.x,
v1.y + v2.y)
end
v1 = Vector(1, 2)
v2 = Vector(3, 4)
v3 = vecAdd(v1, v2)
print(v3) # [_Vector: x=4, y=6]
# Fibers & Coroutine
#-------------------
import Fiber
def fn(p1, p2)
print(yield(42)) # Prints 3.14
end
fb = Fiber.new(fn)
val = Fiber.run(fb, 1, 2)
print(val) ## Prints 42
Fiber.resume(fb, 3.14)
```

View File

@ -1,29 +0,0 @@
<b>
PLEASE NOTE THAT THIS PAGE IS UNDER CONSTRUCTION AND EVERYTHING IS PLACEHOLDER.
</b>
Welcome to the pocketlang documentations, If you haven't installed pocketlang see
[How to Install](Installation.html) reference.
## Hello World
Once you're done installing, lets create the classic Hello World in pocketlang by creating an empty file named `hello.pk`
(Note that pocket lang doesn't enforce the `.pk` extension but it's just a convension).
```ruby
print('Hello World')
```
And run the above script with the following command.
```
$ pocket hello.pk
Hello World
```
## What's Next?
See our examples to make yourself familiar with the pocketlang. (TODO)

View File

@ -1,13 +0,0 @@
Pocketlang is a small, self contained and standalone language which doesn't require any
installer or setup wizard to install. Just download the pre build pocketlang binary (TODO)
or if you have any c99 compatible compiler in your, you can compile it in seconds (see
[How to Build From Source](Build-From-Source.html)) and add the binary path to your
enviornment path variable.
Once you're done, make sure pocketlang is ready to run with the following version command.
```
$ pocket --version
pocketlang 0.1.0
```

View File

@ -1,279 +0,0 @@
:root {
--nav-h-padding: 24px; /* Navigation content horizontal padding. */
--navigation-width: 300px; /* Width of the side navigation bar. */
--content-h-padding: 30px; /* Horizontal padding of the content. */
--navtop-v-margin: 15px; /* Vertical margin. */
--navtop-height: 30px; /* Height of it's content. */
--navbar-height: calc(var(--navtop-v-margin) * 2 + var(--navtop-height));
--pocket-logo-size: 55px;
/* Colors */
--color-title-underline: #d8dee4;
--color-footer-font: #616161;
--color-nav-section-hover: #5988bf;
--color-nav-topics-border: #3b3b3b66;
--color-scrollbar: #a0aec0;
/* Font size */
--fs-nav-title : 20px;
--fs-nav-section: 16px;
--fs-nav-topics: 14px;
--fs-toc-title: 18px;
--fs-toc-item: 15px;
--fs-footer: 13px;
}
/* Scroll bar override (Not works with Firefox and IE) */
::-webkit-scrollbar {
width: var(--scroll-bar-size);
height: var(--scroll-bar-size);
}
::-webkit-scrollbar-thumb { background: var(--color-scrollbar) }
html {
scroll-padding-top: var(--navbar-height);
}
pre:first-line {
line-height: 0;
}
/*****************************************************************************/
/* BASIC LAYOUT STYLES */
/*****************************************************************************/
#navigation {
position: fixed;
width: var(--navigation-width);
height: 100vh;
top: 0; bottom: 0;
z-index: 1;
overflow-y: auto;
background-color: var(--color-theme);
color: white;
user-select: none;
}
#main {
margin-left: var(--navigation-width);
display: flex;
}
#content-body {
padding: 0px var(--content-h-padding);
flex: 1;
}
#table-of-content {
position: sticky;
top: 0;
min-width: 300px;
width: auto;
max-width: 500px;
height: 100vh;
}
/*****************************************************************************/
/* NAVIGATION */
/*****************************************************************************/
#navtop {
padding: var(--nav-h-padding);
}
#nav-title {
font-size: var(--fs-nav-title);
}
#pocket-logo {
width: var(--pocket-logo-size);
height: var(--pocket-logo-size);
}
/* Override the color to match the background. */
#pocket-logo path {
fill:white !important;
}
#toggle-menu {
display: none;
cursor: pointer;
}
.nav-section {
font-size: var(--fs-nav-section);
font-weight: bolder;
padding: 8px var(--nav-h-padding);
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
}
.nav-section:hover, .nav-topics li:hover {
background-color: var(--color-nav-section-hover);
}
.nav-section .collapse-arrow {
transform: rotate(180deg);
}
.nav-section.collapsed .collapse-arrow {
transform: rotate(0deg);
}
.nav-topics.collapsed {
display: none;
}
.nav-topics a {
font-size: var(--fs-nav-topics);
font-weight: normal;
padding: 6px 0px 6px 15px;
margin-left: var(--nav-h-padding);
border-left: 2px solid var(--color-nav-topics-border);
display: block;
text-decoration: none;
}
/*****************************************************************************/
/* TABLE OF CONTENT */
/*****************************************************************************/
#table-of-content {
padding: 30px 30px 0px 10px;
}
#table-of-content h3 {
margin-bottom: 10px;
font-size: var(--fs-toc-title);
}
#table-of-content li {
font-size: var(--fs-toc-item);
margin-top: 5px;
font-weight: 300;
}
#content-footer {
font-weight: bolder;
font-size: var(--fs-footer);
margin-top: 30px;
padding-top: 10px;
margin-bottom: 30px;
border-top: 1px solid var(--color-title-underline);
color: var(--color-footer-font);
}
/*****************************************************************************/
/* MARKDOWN CONTENT */
/*****************************************************************************/
#content-body h1 { /* h1 are page titles. */
font-size: 32px;
margin-top: 25px;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid var(--color-title-underline);
}
#content-body h2 { /* h2 are function names as title. */
font-size: 24px;
margin-top: 30px;
margin-bottom: 15px;
padding-bottom: 5px;
border-bottom: 1px solid var(--color-title-underline);
}
#content-body h3 { /* h3 are sub heading inside a topic. */
font-size: 19px;
margin: 10px 0px;
}
#content-body p {
margin-top: 16px;
margin-bottom: 16px;
line-height: 26px;
}
#content-body ol, #content-body ul {
padding-left: 32px;
margin-bottom: 16px;
}
#content-body li {
margin-top: 8px;
}
/* Since content body <a> tags are auto generated, We cannot (mybe possible)
add the link classes, so we're re-defining the link style here. */
#content-body a:not(.anchor) {
color: var(--color-link);
}
#content-body a:not(.anchor):hover {
text-decoration: underline;
}
/*****************************************************************************/
/* MEDIA SIZE OVERRIDE */
/*****************************************************************************/
@media screen and (max-width: 995px) {
#navigation {
height: 100vh;
width: 100%;
bottom: auto;
}
#navigation.collapsed {
height: auto;
}
#navtop {
padding: var(--navtop-v-margin) 20px;
}
#pocket-logo {
display: none;
}
#navigation.collapsed #navtree {
display: none;
}
#table-of-content {
/* Match the content body padding. */
padding-left: var(--content-h-padding);
top: var(--navbar-height);
}
#main {
margin-top: var(--navbar-height);
margin-left: 0; /* No more sidebar. */
}
#toggle-menu {
display: block;
}
}
@media screen and (max-width: 770px) {
#main {
display: flex;
flex-direction: column;
flex-direction: column-reverse;
}
#table-of-content {
position: relative;
top: 0;
height: auto;
}
}

View File

@ -1,209 +0,0 @@
:root {
--pocket-logo-size: 300px;
--intro-text-max-width: 700px;
--section-max-width: 1100px;
--section-padding: 20px;
--section-margin-bottom: 70px;
--feature-img-size: 64px;
--fs-intro-heading: 40px;
--fs-section-title: 35px;
--fs-feature-title: 24px;
--fs-footer: 13px;
}
html {
scroll-padding-top: var(--navbar-height);
}
pre:first-line {
line-height: 0;
}
body {
background-color: #F6F8F8;
}
p {
margin: 30px 0;
font-size: 16px;
line-height: 28px;
letter-spacing: .6px;
}
/*****************************************************************************/
/* BASIC LAYOUT */
/*****************************************************************************/
#navbar {
/* Other properties are defined at navbar.css */
transition: .2s;
position: fixed;
width: 100%;
z-index: 100;
}
#page-intro {
height: 100vh;
padding-top: var(--navbar-height); /* Because navbar is fixed. */
display: flex;
align-items: center;
justify-content: center;
}
/*****************************************************************************/
/* SECTION */
/*****************************************************************************/
section {
margin: 0 auto var(--section-margin-bottom) auto;
max-width: var(--section-max-width);
padding: var(--section-padding);
}
.section-title {
font-size: var(--fs-section-title);
margin: 0px 0px 30px 0px;
}
/*****************************************************************************/
/* NAVBAR */
/*****************************************************************************/
#navbar.stick {
box-shadow: var(--shadow);
transform: translateY(-5px);
}
#toggle-menu {
cursor: pointer;
display: none;
}
/*****************************************************************************/
/* PAGE INTRO */
/*****************************************************************************/
#intro-text {
max-width: var(--intro-text-max-width);
}
#intro-text h1 {
font-size: var(--fs-intro-heading);
margin-bottom: 30px;
}
#intro-text p {
margin: 30px 0px;
}
#page-intro img {
margin: 0 auto;
height: var(--pocket-logo-size);
width: var(--pocket-logo-size);
}
#intro-buttons {
display: flex;
gap: 15px;
}
/*****************************************************************************/
/* FEATURES SECTION */
/*****************************************************************************/
#features-grid {
display: grid;
grid-gap: 30px;
grid-template-columns: repeat(4, 1fr);;
}
.feature {
display: flex;
flex-direction: column;
}
.feature img {
height: var(--feature-img-size);
margin-bottom: 16px;
}
.feature h2 { /* Feature title. */
font-size: var(--fs-feature-title);
}
.feature p {
letter-spacing: normal;
line-height: normal;
margin: 16px 0;
}
/*****************************************************************************/
/* FOOTER */
/*****************************************************************************/
#footer {
margin-top: 150px;
padding: 20px;
background-color: var(--color-footer-bg);
}
#footer p {
font-size: var(--fs-footer);
text-align: center;
margin: 0;
}
/*****************************************************************************/
/* MEDIA SIZE OVERRIDE */
/*****************************************************************************/
@media screen and (max-height: 500px) {
#page-intro {
height: auto;
padding-top: calc(var(--navbar-height) + 60px);
}
}
@media screen and (max-width: 995px) {
#page-intro {
height: auto;
padding-top: calc(var(--navbar-height) + 30px);
}
#page-intro img {
display: none;
}
#features-grid {
grid-template-columns: repeat(2, 1fr);;
}
}
@media screen and (max-width: 620px) {
#intro-text h1 {
font-size: 35px;
}
#intro-buttons {
flex-direction: column;
}
#intro-buttons a.button {
width: 100%;
text-align: center;
}
#features-grid {
grid-template-columns: repeat(1, 1fr);;
}
.section-title {
font-size: 30px;
}
}

View File

@ -1,42 +0,0 @@
:root {
--navbar-height: 80px;
--fs-nav-title: 40px;
}
#navbar {
height: var(--navbar-height);
display: flex;
align-items: center;
justify-content: space-between;
padding: 15px 50px;
color: white;
background-color: var(--color-theme);
}
#nav-title {
font-family: 'Rage Italic';
font-weight: normal;
font-size: var(--fs-nav-title);
}
#navbar ul li {
display: inline-block;
padding-left: 24px;
}
#navbar ul a:hover {
text-decoration: underline;
}
@media screen and (max-width: 620px) {
#navbar {
justify-content: center;
padding: 10px 50px;
}
#navbar ul {
display: none;
}
}

View File

@ -1,101 +0,0 @@
/* font-family: 'Open Sans', sans-serif; */
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600&display=swap');
/* font-family: 'Montserrat', sans-serif; */
@import url('https://fonts.googleapis.com/css2?family=Montserrat&display=swap');
/* font-family: 'JetBrains Mono', monospace; */
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300&display=swap');
:root {
--scroll-bar-size: 15px;
--color-theme: #336094;
--color-anchor: #cfcfcf;
--color-link: #0969da;
--color-default-font: #24292f;
--color-footer-bg: #e8e8e8;
--shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
--font-mono: 'JetBrains Mono', monospace;
}
/*****************************************************************************/
/* GLOBAL */
/*****************************************************************************/
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Open Sans', sans-serif;
color: inherit;
}
code, code span,
.code, .code span {
font-family: var(--font-mono);
}
a {
text-decoration: none;
}
ul li {
list-style-type: none;
}
.anchor {
text-decoration: none;
color: var(--color-anchor);
transition: .3s;
}
.anchor:hover {
color: var(--color-theme);
}
.link:not(.anchor) {
color: var(--color-link);
}
.link:not(.anchor):hover {
text-decoration: underline;
}
/*****************************************************************************/
/* INLINE */
/*****************************************************************************/
.space-bottom { /* Add margin to have a space after that element. */
margin-bottom: 30px;
}
.flex { display: flex; }
.flac { align-items: center; }
.fljc { justify-content: center; }
.flsb { justify-content: space-between; }
.relative { position: relative; }
/*****************************************************************************/
/* BUTTON */
/*****************************************************************************/
.button {
display: inline-block;
padding: 10px 20px;
color: var(--color-theme);
border: 2px solid var(--color-theme);
border-radius: 5px;
transition: .2s;
font-weight: bolder;
height: 100%;
cursor: pointer;
}
.button:hover {
background-color: var(--color-theme);
color: white;
}

View File

@ -1,161 +0,0 @@
:root {
--scrollbar-size: 10px;
--color-scrollbar: #424242;
--toolbar-height: 65px;
--output-hehgit: 350px;
--color-toolbar-bg: #1b1b1b;
--color-code-example-title: #ffffff99;
--color-editor: #a9b7c6;
--color-output: #afb1b3;
--color-output-bg: #313336;
--color-toolbar-border: #424242;
--color-editor-bg: #1b1b1b;
--color-output-error: #ec5424;
--fs-editor: 20px;
--fs-code-example-title: 12px;
}
/* Scroll bar override (Not works with Firefox and IE) */
::-webkit-scrollbar {
width: var(--scrollbar-size);
height: var(--scrollbar-size);
}
::-webkit-scrollbar-thumb { background: var(--color-scrollbar) } /* Handle */
/* Override navbar color for the dark theme. */
#navbar {
background-color: #27282C;
}
body {
background-color: var(--color-editor-bg);
}
/*****************************************************************************/
/* TOOLBAR */
/*****************************************************************************/
#toolbar {
display: flex;
align-items: center;
padding: 0 30px;
color: white;
height: var(--toolbar-height);
background-color: var(--color-toolbar-bg);
border-bottom: 2px solid var(--color-toolbar-border);
}
#code-example-titles {
white-space: nowrap;
color: var(--color-code-example-title);
overflow: hidden;
display: flex;
flex-grow: 1;
}
#run-button {
display: flex;
align-items: center;
gap: 5px;
padding: 5px 20px;
color: white;
background-color: var(--color-toolbar-bg);
border: 1px solid white;
transition: .2s;
cursor: pointer;
}
#run-button:hover {
background-color: white;
color: var(--color-toolbar-bg);
}
.code-example-title {
cursor: pointer;
padding: 20px 10px;
font-size: var(--fs-code-example-title);
}
.code-example-title:hover,
.code-example-title.active {
color: white;
}
.code-example-title h2 {
font-weight: normal;
}
.code-example-title.active h2 {
font-weight: bolder;
}
/*****************************************************************************/
/* CODE EDITOR */
/*****************************************************************************/
#code-area {
display: flex;
width: 100%;
height: calc(100vh - var(--navbar-height) - var(--toolbar-height));
}
.codejar-wrap {
height: 100%;
flex-basis: 50%;
}
#code-editor {
resize: none !important;
background-color: var(--color-editor-bg);
height: 100%;
color : var(--color-editor);
font-size: var(--fs-editor);
line-height: calc(var(--fs-editor) * 1.4);
font-weight: 400;
padding: 10px;
tab-size: 2;
}
#code-output {
flex-basis: 50%;
overflow-x: scroll;
font-size: var(--fs-editor);
background-color: var(--color-output-bg);
color: var(--color-output);
padding: 16px 32px;
}
#code-output span.error-line {
color: var(--color-output-error);
}
/*****************************************************************************/
/* MEDIA SIZE OVERRIDE */
/*****************************************************************************/
@media screen and (max-width: 995px) {
:root {
--fs-code-example-title: 10px;
--fs-editor: 14px;
}
#code-area {
flex-direction: column;
}
#code-editor::-webkit-scrollbar {
width: 0;
height: 0;
}
#code-output {
height: auto;
min-height: 150px;
}
}

View File

@ -0,0 +1,11 @@
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
Theme: GitHub Dark Dimmed
Description: Dark dimmed theme as seen on github.com
Author: github.com
Maintainer: @Hirse
Updated: 2021-05-15
Colors taken from GitHub's CSS
*/
.hljs{color:#adbac7;background:#22272e}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#f47067}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#dcbdfb}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#6cb6ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#96d0ff}.hljs-built_in,.hljs-symbol{color:#f69d50}.hljs-code,.hljs-comment,.hljs-formula{color:#768390}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#8ddb8c}.hljs-subst{color:#adbac7}.hljs-section{color:#316dca;font-weight:700}.hljs-bullet{color:#eac55f}.hljs-emphasis{color:#adbac7;font-style:italic}.hljs-strong{color:#adbac7;font-weight:700}.hljs-addition{color:#b4f1b4;background-color:#1b4721}.hljs-deletion{color:#ffd8d3;background-color:#78191b}

View File

@ -924,7 +924,7 @@ contains:[{begin:/\\./}]}]}},grmr_ruby:e=>{
const n=e.regex,t="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",a={ const n=e.regex,t="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",a={
/* The below Code was modified by: https://github.com/ThakeeNathees. */ /* The below Code was modified by: https://github.com/ThakeeNathees. */
keyword:"from import as func and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor", keyword:"from import as fn and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",
built_in:"proc lambda",literal:"true false null __file__"}, built_in:"proc lambda",literal:"true false null __file__"},
i={className:"doctag", begin:"@[A-Za-z]+"},r={begin:"#<",end:">"},s=[e.COMMENT("#","$",{contains:[i] i={className:"doctag", begin:"@[A-Za-z]+"},r={begin:"#<",end:">"},s=[e.COMMENT("#","$",{contains:[i]

View File

@ -0,0 +1,13 @@
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
Theme: StackOverflow Light
Description: Light theme as used on stackoverflow.com
Author: stackoverflow.com
Maintainer: @Hirse
Website: https://github.com/StackExchange/Stacks
License: MIT
Updated: 2021-05-15
Updated for @stackoverflow/stacks v0.64.0
Code Blocks: /blob/v0.64.0/lib/css/components/_stacks-code-blocks.less
Colors: /blob/v0.64.0/lib/css/exports/_stacks-constants-colors.less
*/.hljs{color:#2f3337;background:#f6f6f6}.hljs-subst{color:#2f3337}.hljs-comment{color:#656e77}.hljs-attr,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-section,.hljs-selector-tag{color:#015692}.hljs-attribute{color:#803378}.hljs-name,.hljs-number,.hljs-quote,.hljs-selector-id,.hljs-template-tag,.hljs-type{color:#b75501}.hljs-selector-class{color:#015692}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-string,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#54790d}.hljs-meta,.hljs-selector-pseudo{color:#015692}.hljs-built_in,.hljs-literal,.hljs-title{color:#b75501}.hljs-bullet,.hljs-code{color:#535a60}.hljs-meta .hljs-string{color:#54790d}.hljs-deletion{color:#c02d2e}.hljs-addition{color:#2f6f44}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}

View File

@ -1,74 +0,0 @@
/**
* The source is modified by ThakeeNathees (github.com/ThakeeNathees)
* to match the theme of the project.
*/
code {
padding: 0 3px;
background:#1b1b1b;
}
pre code.hljs{
display:block;
overflow-x:auto;
padding:1em
}
code.hljs{
padding:3px 5px
}
.hljs{
color:#a9b7c6;
background:#edf2f7;
border-radius: 3px;
}
.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{
color: #ca7b3a;
font-weight: bold;
}
.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{
color: #cc99cc;
}
.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{
color:#6897BB
}
.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{
color:#6A873F
}
.hljs-built_in,.hljs-symbol{
color:#e36209
}
.hljs-code,.hljs-comment,.hljs-formula{
color:#6a737d
}
.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{
color:#6A873F
}
.hljs-subst{
color:#24292e
}
.hljs-section{
color:#005cc5;
font-weight:700
}
.hljs-bullet{
color:#735c0f
}
.hljs-emphasis{
color:#24292e;
font-style:italic
}
.hljs-strong{
color:#24292e;
font-weight:700
}
.hljs-addition{
color:#22863a;
background-color:#f0fff4
}
.hljs-deletion{
color:#b31d28;
background-color:#ffeef0
}

View File

@ -1,74 +0,0 @@
/**
* The source is modified by ThakeeNathees (github.com/ThakeeNathees)
* to match the theme of the project.
*/
code {
padding: 0 3px;
background:#edf2f7;
border-radius: 3px;
}
pre code.hljs{
display:block;
overflow-x:auto;
padding:1em
}
code.hljs{
padding:3px 5px
}
.hljs{
color:#24292e;
background:#edf2f7;
border-radius: 3px;
}
.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{
color:#2b6cb0;
}
.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{
color:#6f42c1
}
.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{
color:#e18a8a
}
.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{
color:#219321
}
.hljs-built_in,.hljs-symbol{
color:#e36209
}
.hljs-code,.hljs-comment,.hljs-formula{
color:#6a737d
}
.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{
color:#219321
}
.hljs-subst{
color:#24292e
}
.hljs-section{
color:#005cc5;
font-weight:700
}
.hljs-bullet{
color:#735c0f
}
.hljs-emphasis{
color:#24292e;
font-style:italic
}
.hljs-strong{
color:#24292e;
font-weight:700
}
.hljs-addition{
color:#22863a;
background-color:#f0fff4
}
.hljs-deletion{
color:#b31d28;
background-color:#ffeef0
}

View File

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="100mm"
height="100mm"
viewBox="0 0 100 100"
version="1.1"
id="svg34090"
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
sodipodi:docname="parallel.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview34092"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.0179639"
inkscape:cx="124.26766"
inkscape:cy="87.9206"
inkscape:window-width="1920"
inkscape:window-height="1001"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:current-layer="layer9" />
<defs
id="defs34087" />
<g
inkscape:groupmode="layer"
id="layer9"
inkscape:label="arrow2">
<path
style="fill:#1769e0;stroke:#000000;stroke-width:0.499999;stroke-dasharray:1.5, 0.499999;stroke-opacity:0;fill-opacity:1"
d="M 6.0649751,21.13552 6.0190284,35.976329 25.959932,35.907411 58.007813,79.556852 73.377011,79.304146 73.606744,89.527305 91.847616,72.710783 73.560796,54.74559 73.399982,65.290376 63.705213,65.129563 31.335704,20.836865 Z"
id="path35367" />
</g>
<g
inkscape:groupmode="layer"
id="layer8"
inkscape:label="arrow1"
style="display:inline">
<path
style="fill:#508ef5;stroke:#000000;stroke-width:0.499999;stroke-dasharray:1.5, 0.499999;stroke-opacity:0;fill-opacity:1"
d="m 25.427006,71.029728 -19.014167,0.34704 -0.121991,14.5665 26.706187,-0.19494 31.39022,-43.94223 9.156403,-0.178211 0.324895,10.42906 18.356442,-18.096531 -18.421421,-17.024382 0.03249,10.85142 -16.277129,-0.259914 -15.39992,21.540393"
id="path34229"
sodipodi:nodetypes="cccccccccccc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,51 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="60mm"
height="53mm"
viewBox="0 0 60 53"
version="1.1"
id="svg5"
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
sodipodi:docname="pocketlang.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2"
inkscape:cx="127.75"
inkscape:cy="137.75"
inkscape:window-width="1920"
inkscape:window-height="1001"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:current-layer="layer2"
inkscape:snap-text-baseline="true"
width="199mm"
height="84mm" />
<defs
id="defs2" />
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="pocket"
style="display:inline">
<path
style="display:inline;fill:#02509b;fill-opacity:1;stroke:#02509b;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 2.3111481,1.542641 58.132911,1.605311 54.211225,37.618521 30.466656,52.473331 5.9787752,36.899821 Z"
id="path888"
sodipodi:nodetypes="cccccc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1,73 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="100mm"
height="100mm"
viewBox="0 0 100 100"
version="1.1"
id="svg5"
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
sodipodi:docname="gc.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.50898197"
inkscape:cx="-38.31177"
inkscape:cy="132.61766"
inkscape:window-width="1920"
inkscape:window-height="1001"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:current-layer="layer4"
width="209mm" />
<defs
id="defs2" />
<g
inkscape:groupmode="layer"
id="layer4"
inkscape:label="arrows">
<path
style="fill:#a1c057;fill-opacity:1;stroke:#000000;stroke-width:0.499999;stroke-dasharray:1.5, 0.499999;stroke-opacity:0"
d="m 44.675233,7.9890623 15.457148,27.7091727 -6.743034,4.972048 23.93828,6.57039 6.34065,-24.168 -7.02985,3.5379 L 64.908136,7.9494173 Z"
id="path30125"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:#a1c057;fill-opacity:1;stroke:#000000;stroke-width:0.499999;stroke-dasharray:1.5, 0.499999;stroke-opacity:0"
d="m 73.330257,57.027343 14.19755,-6.70823 7.81095,16.63273 -17.04625,0.27568 z"
id="path30160"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#a1c057;fill-opacity:1;stroke:#000000;stroke-width:0.499999;stroke-dasharray:1.5, 0.499999;stroke-opacity:0"
d="m 96.119857,69.616753 -5.97308,19.29765 -25.91399,-0.11486 -0.0459,8.38528 -19.15981,-17.87329 18.42466,-18.5625 0.13784,9.05151 z"
id="path30370"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:#a1c057;fill-opacity:1;stroke:#000000;stroke-width:0.499999;stroke-dasharray:1.5, 0.499999;stroke-opacity:0"
d="m 29.26729,71.936283 10.659657,0.27568 0.27568,16.51787 -18.654396,-0.0911 z"
id="path30372"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#a1c057;fill-opacity:1;stroke:#000000;stroke-width:0.499999;stroke-dasharray:1.5, 0.499999;stroke-opacity:0"
d="m 4.134401,72.511403 14.425376,15.5473 14.612991,-31.30704 8.224469,4.13521 -9.327194,-25.041 -24.2599,9.05152 7.902848,3.99737 z"
id="path30374"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:#a1c057;fill-opacity:1;stroke:#000000;stroke-width:0.499999;stroke-dasharray:1.5, 0.499999;stroke-opacity:0"
d="m 32.966786,25.575993 9.465041,-15.43812 8.77583,15.02459 -6.2947,8.72989 z"
id="path30376"
sodipodi:nodetypes="ccccc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="100mm"
height="100mm"
viewBox="0 0 100 100"
version="1.1"
id="svg5"
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
sodipodi:docname="pocketlang.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.5"
inkscape:cx="119"
inkscape:cy="-87"
inkscape:window-width="1920"
inkscape:window-height="1001"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
inkscape:snap-text-baseline="true"
width="199mm" />
<defs
id="defs2" />
<g
inkscape:groupmode="layer"
id="layer1"
inkscape:label="gear"
style="display:inline">
<path
id="path25860"
style="fill:#423242;fill-opacity:1;stroke:#020000;stroke-width:0.386648;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0"
inkscape:transform-center-y="4.9342434e-05"
d="m 29.790826,33.91526 a 29.910114,29.910114 0 0 0 -9.016695,3.466483 l 0.08978,4.453959 a 25.867964,25.867964 0 0 0 -5.589893,5.132439 L 11.009942,46.610772 A 29.910114,29.910114 0 0 0 7.0393484,55.3996 l 2.9485995,2.915788 a 25.867964,25.867964 0 0 0 -0.4937418,4.940797 25.867964,25.867964 0 0 0 0.2382273,3.416441 L 6.650911,69.370909 a 29.910114,29.910114 0 0 0 3.516557,9.037388 l 4.182933,-0.0899 a 25.867964,25.867964 0 0 0 5.282615,5.45697 l -0.338368,4.270995 a 29.910114,29.910114 0 0 0 8.951096,4.025823 l 3.048728,-3.276614 a 25.867964,25.867964 0 0 0 4.067263,0.328057 25.867964,25.867964 0 0 0 2.677552,-0.155187 l 3.012477,3.656408 a 29.910114,29.910114 0 0 0 9.049492,-3.145447 l -0.09842,-4.901051 a 25.867964,25.867964 0 0 0 5.405181,-4.985699 l 5.203203,0.43673 a 29.910114,29.910114 0 0 0 3.906725,-8.174207 l -3.770342,-3.728909 a 25.867964,25.867964 0 0 0 0.481648,-4.869998 25.867964,25.867964 0 0 0 -0.20545,-3.252416 l 4.022382,-3.521782 a 29.910114,29.910114 0 0 0 -3.293866,-8.3382 l -5.315408,0.113866 a 25.867964,25.867964 0 0 0 -5.201434,-5.422411 l 0.402241,-5.087537 a 29.910114,29.910114 0 0 0 -8.657614,-3.625304 l -3.366377,3.620132 a 25.867964,25.867964 0 0 0 -4.251975,-0.353883 25.867964,25.867964 0 0 0 -2.589519,0.146756 z m 6.009405,15.065808 A 14.057662,14.057662 0 0 1 49.857849,63.038664 14.057662,14.057662 0 0 1 35.800231,77.096291 14.057662,14.057662 0 0 1 21.74261,63.038664 14.057662,14.057662 0 0 1 35.800231,48.981068 Z"
inkscape:transform-center-x="-6.7199755e-06" />
<path
id="path52641"
style="fill:#423242;fill-opacity:1;stroke:#020000;stroke-width:0.230818;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0"
inkscape:transform-center-y="2.9635219e-05"
d="m 70.664075,11.59577 a 17.855509,17.855509 0 0 0 -5.382717,2.069394 l 0.0536,2.65889 a 15.442457,15.442457 0 0 0 -3.337011,3.063924 l -2.545535,-0.21334 a 17.855509,17.855509 0 0 0 -2.370334,5.246687 l 1.760232,1.740644 a 15.442457,15.442457 0 0 0 -0.29475,2.949519 15.442457,15.442457 0 0 0 0.142214,2.039521 l -1.839583,1.6108 a 17.855509,17.855509 0 0 0 2.099287,5.39507 l 2.497095,-0.05367 a 15.442457,15.442457 0 0 0 3.153575,3.25766 l -0.201996,2.549665 a 17.855509,17.855509 0 0 0 5.343556,2.403304 l 1.820006,-1.956047 a 15.442457,15.442457 0 0 0 2.428043,0.195841 15.442457,15.442457 0 0 0 1.598424,-0.09264 l 1.798365,2.182774 a 17.855509,17.855509 0 0 0 5.4023,-1.877744 l -0.05871,-2.925792 a 15.442457,15.442457 0 0 0 3.226743,-2.976324 l 3.106163,0.260716 a 17.855509,17.855509 0 0 0 2.332208,-4.879775 l -2.250787,-2.226055 a 15.442457,15.442457 0 0 0 0.287533,-2.907254 15.442457,15.442457 0 0 0 -0.122655,-1.941602 l 2.401254,-2.102407 a 17.855509,17.855509 0 0 0 -1.966348,-4.977675 l -3.17315,0.06797 a 15.442457,15.442457 0 0 0 -3.105114,-3.237028 l 0.24013,-3.037118 a 17.855509,17.855509 0 0 0 -5.16836,-2.164206 L 76.52812,13.88059 a 15.442457,15.442457 0 0 0 -2.538311,-0.211258 15.442457,15.442457 0 0 0 -1.545871,0.08761 z m 3.587448,8.993869 a 8.3920342,8.3920342 0 0 1 8.392007,8.391995 8.3920342,8.3920342 0 0 1 -8.392007,8.392013 8.3920342,8.3920342 0 0 1 -8.39201,-8.392013 8.3920342,8.3920342 0 0 1 8.39201,-8.391995 z"
inkscape:transform-center-x="-6.8961349e-06" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -1,86 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="60mm"
height="85mm"
viewBox="0 0 60 85"
version="1.1"
id="pocket-logo"
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
sodipodi:docname="pocketlang.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2"
inkscape:cx="187.75"
inkscape:cy="137.75"
inkscape:window-width="1920"
inkscape:window-height="1001"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:current-layer="layer6"
inkscape:snap-text-baseline="true"
width="199mm" />
<defs
id="defs2" />
<g
inkscape:groupmode="layer"
id="layer1"
inkscape:label="gear"
style="display:inline">
<path
id="path7786"
style="fill:#433242;fill-opacity:1;stroke:#020000;stroke-width:0.115739;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0"
inkscape:transform-center-y="-1.9949254e-06"
d="m 34.643917,1.118321 a 8.9533033,8.9533033 0 0 0 -2.69906,1.0376614 l 0.02687,1.3332539 A 7.7433246,7.7433246 0 0 0 30.298448,5.0255765 L 29.02204,4.9186054 a 8.9533033,8.9533033 0 0 0 -1.188559,2.6308473 l 0.882634,0.8728154 a 7.7433246,7.7433246 0 0 0 -0.147796,1.4789789 7.7433246,7.7433246 0 0 0 0.07131,1.022678 l -0.922422,0.807701 a 8.9533033,8.9533033 0 0 0 1.052647,2.705262 l 1.25212,-0.02687 a 7.7433246,7.7433246 0 0 0 1.5813,1.633493 l -0.101287,1.278475 a 8.9533033,8.9533033 0 0 0 2.679424,1.205092 l 0.912607,-0.980818 a 7.7433246,7.7433246 0 0 0 1.217496,0.09819 7.7433246,7.7433246 0 0 0 0.801499,-0.04651 l 0.901756,1.094505 a 8.9533033,8.9533033 0 0 0 2.708878,-0.941544 l -0.02946,-1.467093 a 7.7433246,7.7433246 0 0 0 1.617988,-1.492417 l 1.557528,0.130741 a 8.9533033,8.9533033 0 0 0 1.16944,-2.446877 L 43.910528,11.359044 A 7.7433246,7.7433246 0 0 0 44.054705,9.901251 7.7433246,7.7433246 0 0 0 43.993215,8.927666 L 45.197278,7.8734641 A 8.9533033,8.9533033 0 0 0 44.211292,5.3774934 l -1.591117,0.034105 A 7.7433246,7.7433246 0 0 0 41.063163,3.788443 L 41.18357,2.2655384 A 8.9533033,8.9533033 0 0 0 38.591997,1.1803314 L 37.584305,2.2639879 A 7.7433246,7.7433246 0 0 0 36.311517,2.1580514 7.7433246,7.7433246 0 0 0 35.53637,2.2019754 Z m 1.798857,4.5098017 a 4.2080248,4.2080248 0 0 1 4.208012,4.2080123 4.2080248,4.2080248 0 0 1 -4.208012,4.20801 4.2080248,4.2080248 0 0 1 -4.208013,-4.20801 4.2080248,4.2080248 0 0 1 4.208013,-4.2080123 z" />
<path
id="path25778"
style="fill:#433242;fill-opacity:1;stroke:#020000;stroke-width:0.115739;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0"
inkscape:transform-center-y="-1.9949254e-06"
d="m 47.399493,19.594186 a 8.9533033,8.9533033 0 0 0 -2.69906,1.03766 l 0.02687,1.33325 a 7.7433246,7.7433246 0 0 0 -1.67328,1.53634 l -1.276409,-0.10697 a 8.9533033,8.9533033 0 0 0 -1.188558,2.63085 l 0.882634,0.87281 a 7.7433246,7.7433246 0 0 0 -0.147796,1.47898 7.7433246,7.7433246 0 0 0 0.07131,1.02268 l -0.922422,0.8077 a 8.9533033,8.9533033 0 0 0 1.052647,2.70526 l 1.25212,-0.0269 a 7.7433246,7.7433246 0 0 0 1.5813,1.63349 l -0.101287,1.27848 a 8.9533033,8.9533033 0 0 0 2.679424,1.20509 l 0.912607,-0.98082 a 7.7433246,7.7433246 0 0 0 1.217496,0.0982 7.7433246,7.7433246 0 0 0 0.801499,-0.0465 l 0.901756,1.09451 a 8.9533033,8.9533033 0 0 0 2.708878,-0.94155 l -0.02946,-1.46709 a 7.7433246,7.7433246 0 0 0 1.617988,-1.49242 l 1.557528,0.13074 a 8.9533033,8.9533033 0 0 0 1.16944,-2.44687 l -1.128615,-1.11622 a 7.7433246,7.7433246 0 0 0 0.144177,-1.45779 7.7433246,7.7433246 0 0 0 -0.0615,-0.97358 l 1.204061,-1.0542 a 8.9533033,8.9533033 0 0 0 -0.985986,-2.49597 l -1.591117,0.0341 a 7.7433246,7.7433246 0 0 0 -1.556999,-1.62314 l 0.120407,-1.52291 a 8.9533033,8.9533033 0 0 0 -2.591573,-1.0852 l -1.007692,1.08365 a 7.7433246,7.7433246 0 0 0 -1.272788,-0.10593 7.7433246,7.7433246 0 0 0 -0.775148,0.0439 z m 1.798857,4.5098 a 4.2080248,4.2080248 0 0 1 4.208012,4.20801 4.2080248,4.2080248 0 0 1 -4.208012,4.20801 4.2080248,4.2080248 0 0 1 -4.208013,-4.20801 4.2080248,4.2080248 0 0 1 4.208013,-4.20801 z" />
<path
id="path25860"
style="fill:#423242;fill-opacity:1;stroke:#020000;stroke-width:0.233957;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0"
inkscape:transform-center-y="2.7909511e-05"
d="m 16.864499,16.897796 a 18.098269,18.098269 0 0 0 -5.455899,2.09753 l 0.05432,2.69504 a 15.65241,15.65241 0 0 0 -3.3823803,3.10558 l -2.5801414,-0.21624 a 18.098269,18.098269 0 0 0 -2.4025611,5.31802 l 1.7841639,1.76431 a 15.65241,15.65241 0 0 0 -0.2987575,2.98962 15.65241,15.65241 0 0 0 0.1441486,2.06725 l -1.8645916,1.6327 a 18.098269,18.098269 0 0 0 2.1278282,5.46842 l 2.5310449,-0.0544 a 15.65241,15.65241 0 0 0 3.1964503,3.30195 l -0.204743,2.58433 a 18.098269,18.098269 0 0 0 5.416207,2.43598 l 1.84475,-1.98264 a 15.65241,15.65241 0 0 0 2.461055,0.1985 15.65241,15.65241 0 0 0 1.620156,-0.0939 l 1.822815,2.21245 a 18.098269,18.098269 0 0 0 5.475745,-1.90327 l -0.05955,-2.96557 a 15.65241,15.65241 0 0 0 3.270613,-3.01679 l 3.148397,0.26426 a 18.098269,18.098269 0 0 0 2.363915,-4.94612 l -2.281391,-2.25632 a 15.65241,15.65241 0 0 0 0.29144,-2.94678 15.65241,15.65241 0 0 0 -0.124316,-1.968 l 2.433898,-2.13099 a 18.098269,18.098269 0 0 0 -1.993081,-5.04535 l -3.216293,0.0689 a 15.65241,15.65241 0 0 0 -3.147329,-3.28104 l 0.243391,-3.07841 a 18.098269,18.098269 0 0 0 -5.238623,-2.19363 l -2.036956,2.1905 a 15.65241,15.65241 0 0 0 -2.572822,-0.21413 15.65241,15.65241 0 0 0 -1.566889,0.0888 z m 3.636222,9.11615 a 8.5061304,8.5061304 0 0 1 8.506105,8.50609 8.5061304,8.5061304 0 0 1 -8.506105,8.50611 8.5061304,8.5061304 0 0 1 -8.506106,-8.50611 8.5061304,8.5061304 0 0 1 8.506106,-8.50609 z"
inkscape:transform-center-x="-4.7871538e-06" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="pocket"
style="display:inline">
<path
style="display:inline;fill:#02509b;fill-opacity:1;stroke:#02509b;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 2.1788564,32.895766 58.000619,32.958436 54.078933,68.971646 30.334364,83.826456 5.8464835,68.252946 Z"
id="path888"
sodipodi:nodetypes="cccccc" />
</g>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="thread">
<path
style="fill:#ffffff;fill-opacity:0;stroke:#ffffff;stroke-width:0.499999;stroke-miterlimit:4;stroke-dasharray:1.5, 0.499999;stroke-dashoffset:0;stroke-opacity:1"
d="M 5.0192948,35.429917 55.252601,35.59362 52.212412,67.188217 30.276266,81.523887 8.0828715,67.305149 Z"
id="path2442" />
<path
style="fill:#ffffff;fill-opacity:0;stroke:#ffffff;stroke-width:0.499999;stroke-miterlimit:4;stroke-dasharray:1.5, 0.499999;stroke-dashoffset:0;stroke-opacity:1"
d="M 6.9837256,55.471789 C 11.754487,55.05084 23.962023,56.9685 27.703797,59.120018 c 3.250097,1.868804 9.775382,8.138358 8.980257,11.41241 -0.977976,4.026972 -3.414369,5.706203 -6.594878,5.799749 -3.180507,0.09354 -6.361015,-2.666014 -6.127154,-6.969054 0.233861,-4.303041 6.828738,-10.196331 12.020448,-11.739813 5.191709,-1.543481 16.884751,-1.870887 16.884751,-1.870887"
id="path2840"
sodipodi:nodetypes="csssssc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="100mm"
height="100mm"
viewBox="0 0 100 100"
version="1.1"
id="svg31586"
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
sodipodi:docname="repl.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview31588"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.0179639"
inkscape:cx="184.1912"
inkscape:cy="175.35002"
inkscape:window-width="1920"
inkscape:window-height="1001"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:current-layer="layer6" />
<defs
id="defs31583" />
<g
inkscape:groupmode="layer"
id="layer6"
inkscape:label="cmd"
style="display:inline">
<path
id="path33561"
style="fill:#4b4c4b;fill-opacity:1;stroke:#000000;stroke-width:0.499999;stroke-dasharray:1.5, 0.499999;stroke-opacity:0"
d="m 4.6062915,18.400147 -0.1834513,64.6467 H 94.937728 l -0.09199,-64.6467 z M 22.125119,32.846811 40.156575,50.650891 22.222787,68.58468 17.349183,63.516771 30.312731,50.618334 17.219475,37.687342 Z m 46.990411,30.718538 -0.04599,6.340697 -25.821679,0.04599 v -6.340697 z" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1,12 +0,0 @@
$("#toggle-menu").onclick = function() {
$("#navigation").classList.toggle("collapsed");
}
$$(".nav-section").forEach(function(el) {
el.onclick = function() {
el.classList.toggle("collapsed");
el.nextElementSibling.classList.toggle("collapsed");
}
});

View File

@ -1,8 +0,0 @@
window.addEventListener('scroll', function() {
if (window.scrollY > 30) {
$("#navbar").classList.add("stick");
} else {
$("#navbar").classList.remove("stick");
}
});

View File

@ -1,10 +0,0 @@
let $ = document.querySelector.bind(document);
let $$ = document.querySelectorAll.bind(document);
// Syntax highlighting.
document.addEventListener('DOMContentLoaded', (event) => {
$$('.highlight').forEach(function(el) {
hljs.highlightElement(el);
});
});

View File

@ -1,100 +0,0 @@
let examples = {
"Simple" :`\
# A recursive fibonacci function.
def fib(n)
if n < 2 then return n end
return fib(n-1) + fib(n-2)
end
# Prints all fibonacci from 0 to 10 exclusive.
for i in 0..10
print(\"fib($i) = \${fib(i)}\")
end`,
"Concurrent" : `\
import Fiber
def fn()
print('running')
yield(42) # Return 42.
print('resumed')
end
fb = Fiber.new(fn)
val = Fiber.run(fb) # Prints 'running'.
print(val) # Prints 42.
Fiber.resume(fb) # Prints 'resumed'.`,
"Object-Oriented" : `\
## NOTE THAT CLASSES WIP AND WILL BE CHANGED.
class _Vector
x = 0; y = 0
end
def Vector(x, y)
v = _Vector()
v.x = x; v.y = y
return v
end
def add(v1, v2)
return Vector(v1.x + v2.x,
v1.y + v2.y)
end
v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(add(v1, v2))
`,
}
let code_editor = $("#code-editor");
let code_example_titles = $$(".code-example-title");
let code_highlight_fn = withLineNumbers(function(editor) {
editor.textContent = editor.textContent;
html = hljs.highlight(editor.textContent, {language : 'ruby'}).value;
// https://github.com/antonmedv/codejar/issues/22#issuecomment-773894139
if (html.length > 2 && html.substring(html.length - 2, html.length) != '\n\n') {
html += '\n'
}
editor.innerHTML = html;
});
function setCode(el) {
code_example_titles.forEach(function(el) {
el.classList.remove("active");
});
el.classList.add("active");
code_editor.textContent = examples[el.getAttribute("name")];
code_highlight_fn(code_editor);
}
setCode(code_example_titles[0]);
code_example_titles.forEach(function(el) {
el.onclick = function() {
setCode(el);
}
});
CodeJar(code_editor, code_highlight_fn, { indentOn: /[(\[{]$/});
var runSource; // Native function.
window.onload = function() {
// Module will be defined by pocketlang.js when the page is loaded.
runSource = Module.cwrap('runSource', 'number', ['string']);
$("#run-button").onclick = function() {
$("#code-output").classList.remove("has-error");
$('#code-output').innerText = '';
const source = code_editor.textContent;
runSource(source);
}
}

50
docs/static/main.js vendored Normal file
View File

@ -0,0 +1,50 @@
// If you know how to do this properly feel free to open a PR.
// This is a quick and very dirty script to change the theme of the page.
// Icons Downloaded from : https://remixicon.com/
const MOON = `<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-6.671-5.575A8 8 0 1 0 16.425 5.328a8.997 8.997 0 0 1-2.304 8.793 8.997 8.997 0 0 1-8.792 2.304z"/></svg>`;
const SUN = `<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></svg>`;
function createThemeButton() {
let div = document.createElement('button');
div.innerHTML = "";
div.innerHTML += `<div class="sidebar-toggle-button" id="icon-moon" style="display:none">${MOON.trim()}</div>`;
div.innerHTML += `<div class="sidebar-toggle-button" id="icon-sun">${SUN.trim()}</div>`;
div.classList.add('sidebar-toggle');
div.classList.add('theme');
return div;
}
function toggleTheme() {
function _toggleTheme(enable, disable) {
document.querySelectorAll(`.theme-${enable}`).forEach(function(el) {
el.removeAttribute("disabled");
});
document.querySelectorAll(`.theme-${disable}`).forEach(function(el) {
el.setAttribute("disabled", '');
});
}
// Yup, I have no idea how JS/CSS works together.
const isLight = !document.querySelector(".theme-light").hasAttribute("disabled");
if (isLight) {
_toggleTheme('dark', 'light');
document.querySelector("#icon-sun").style.display = 'flex';
document.querySelector("#icon-moon").style.display = 'none';
} else {
_toggleTheme('light', 'dark');
document.querySelector("#icon-moon").style.display = 'flex';
document.querySelector("#icon-sun").style.display = 'none';
}
}
function onDocsifyReady() {
// TODO: store the theme in the localStorage.
let theme_toggle = createThemeButton();
let main = document.querySelector('main');
let sidebar_toggle = main.querySelector('.sidebar-toggle');
main.insertBefore(theme_toggle, sidebar_toggle);
theme_toggle.onclick = function() {
toggleTheme();
}
}

View File

@ -1,143 +0,0 @@
/* PrismJS 1.23.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+ruby */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
font-size: 1em;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
code[class*="language-"]::selection, code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.token.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
/* This background color was intended by the author of this theme. */
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}

File diff suppressed because one or more lines are too long

50
docs/static/style.css vendored Normal file
View File

@ -0,0 +1,50 @@
/* font-family: 'Source Code Pro', monospace; */
@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap');
/*****************************************************************************/
/* DOCSIFY SYTLE OVERRIDE */
/*****************************************************************************/
.sidebar-toggle.theme .sidebar-toggle-button {
top: 0;
}
.sidebar-toggle.theme {
top: calc(var(--sidebar-toggle-offset-top) + 40px);
}
.sidebar-toggle.theme div {
display: flex;
align-items: center;
justify-content: center;
}
.center {
display: flex;
align-items: center;
justify-content: center;
}
.text-center {
text-align: center;
}
.button {
cursor: pointer;
text-align: center;
min-width: 100px;
background-color: #0B87DA;
padding: 10px;
margin-left: 10px;
margin-right: 10px;
}
.button:hover {
background-color: #0a75bc;
}
a.button, a.button:hover {
color: white;
text-decoration: none;
}

View File

@ -1,71 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg" href="{{ STATIC_DIR }}img/favicon.svg">
<script src="{{ STATIC_DIR }}highlight.js/highlight.min.js"></script>
<link rel="stylesheet" href="{{ STATIC_DIR }}highlight.js/theme_docs.css">
<link rel="stylesheet" href="{{ STATIC_DIR }}rage_font/style.css">
<link rel="stylesheet" href="{{ STATIC_DIR }}css/style.css">
<link rel="stylesheet" href="{{ STATIC_DIR }}css/docs.css">
<title>Docs - pocketlang</title>
</head>
<body>
<!-- Navigation bar at the side of the page. -->
<div id="navigation" class="collapsed">
<!-- This tag will become top navbar for smaller screen (otherwise navigation top). -->
<div id="navtop">
<div class="flex flac flsb">
<a href="{{ URL_POCKET_HOME }}">
<div class="flex flac">
{{ LOGO_WHITE }}
<h1 id="nav-title">Pocketlang Docs</h1>
</div>
</a>
<!-- Toggle menu icon. -->
<svg xmlns="http://www.w3.org/2000/svg" id="toggle-menu" viewBox="0 0 20 20" width="30" height="30">
<path d="M0 0h24v24H0z" fill="none"></path>
<path fill="currentColor" d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path>
</svg>
</div>
</div>
<!-- Generated navigation tree. -->
<div id="navtree" class="space-bottom">
<ul>
{{ NAVIGATION_TREE }}
</ul>
</div>
</div>
<!-- Main content of the page. Divided into the doc content and the table of content. -->
<div id="main">
<!-- Documentation body -->
<div id="content-body">
<h1>{{ PAGE_TITLE }} <a href="#{{ PAGE_TITLE }}" id="{{ PAGE_TITLE }}" class="anchor">#</a></h2> </h1>
<!-- Generated page content. -->
{{ PAGE_CONTENT }}
<!-- Footer. -->
<div id="content-footer">
<p>Made by <a href="https://www.github.com/ThakeeNathees">ThakeeNathees</a>
and contributers on <a href="https://www.github.com/">github</a>.</p>
</div>
</div>
<!-- Table of content. -->
<div id="table-of-content">
<h3>In this page</h3>
<ul>
{{ TOC_ENTRIES }}
</ul>
</div>
</div>
<script src="{{ STATIC_DIR }}js/main.js"></script>
<script src="{{ STATIC_DIR }}js/docs.js"></script>
</body>
</html>

View File

@ -1,77 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg" href="{{ STATIC_DIR }}img/favicon.svg">
<script src="{{ STATIC_DIR }}highlight.js/highlight.min.js"></script>
<link rel="stylesheet" href="{{ STATIC_DIR }}highlight.js/theme_docs.css">
<link rel="stylesheet" href="{{ STATIC_DIR }}rage_font/style.css">
<link rel="stylesheet" href="{{ STATIC_DIR }}css/style.css">
<link rel="stylesheet" href="{{ STATIC_DIR }}css/navbar.css">
<link rel="stylesheet" href="{{ STATIC_DIR }}css/home.css">
<title>Pocketlang</title>
</head>
<body>
<!-- Sticky navigation bar at the top. -->
<div id="navbar">
<a href="#"><h1 id="nav-title">pocketlang</h1></a>
<div>
<ul>
<li><a href="{{ DOCS_URL }}Reference/Getting-Started.html">Docs</a></li>
<li><a href="">Download</a></li>
<li><a target="_blank" href="https://www.github.com/ThakeeNathees/pocketlang/">Github</a></li>
</ul>
</div>
</div>
<div id="main">
<!-- Page intro section which will be 100vh. -->
<section id="page-intro">
<div id="intro-text">
<h1>Pocketlang is a small fast and friendly language</h1>
<p>
It's a dynamic typed, highlevel language language designed for scripting and
embedding easily. Supports classes, first class functions, closures, REPL,
garbage collection, fiber based concurrency, and more.
</p>
<div id="intro-buttons">
<a class="button" href="{{ DOCS_URL }}Reference/Getting-Started.html">Get Started</a>
<a class="button" href="try-online.html">Try Online</a>
</div>
</div>
<img src="{{ STATIC_DIR }}img/pocketlang.svg">
</section>
<!-- What it looks like? -->
<section id="what-pocketlang-looks-like">
<h1 class="section-title">What pocketlang looks like?</h1>
<p>
With mixed syntax of ruby and python, that can be learned in less than an hour, and it's
easy to embed into another application for scripting. Here is a smaple pocketlang code.
</p>
<pre><code class="highlight ruby"><pre><code class="highlight ruby">{{ WHAT_IT_LOOKS_LIKE }}</code></pre></code></pre>
</section>
<section id="features">
<div id="features-grid">
{{ POCKET_FEATURES }}
</div>
</section>
<div id="footer">
<p>Made by <a class="link" href="https://www.github.com/ThakeeNathees">ThakeeNathees</a>
and contributers on <a class="link" href="https://www.github.com/">github</a>.</p>
</div>
</div>
<script src="{{ STATIC_DIR }}js/main.js"></script>
<script src="{{ STATIC_DIR }}js/home.js"></script>
</body>
</html>

View File

@ -1,60 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg" href="{{ STATIC_DIR }}img/favicon.svg">
<script src="{{ STATIC_DIR }}codejar/linenumbers.js"></script>
<script src="{{ STATIC_DIR }}codejar/codejar.js"></script>
<script src="{{ STATIC_DIR }}highlight.js/highlight.min.js"></script>
<link rel="stylesheet" href="{{ STATIC_DIR }}highlight.js/theme_dark.css">
<link rel="stylesheet" href="{{ STATIC_DIR }}rage_font/style.css">
<link rel="stylesheet" href="{{ STATIC_DIR }}css/style.css">
<link rel="stylesheet" href="{{ STATIC_DIR }}css/navbar.css">
<link rel="stylesheet" href="{{ STATIC_DIR }}css/try_online.css">
<title>Pocketlang - Try Online</title>
</head>
<body>
<!-- Navigation bar at the top. -->
<div id="navbar">
<a href="index.html"><h1 id="nav-title">pocketlang</h1></a>
<div>
<ul>
<li><a href="{{ DOCS_URL }}Reference/Getting-Started.html">Docs</a></li>
<li><a href="">Download</a></li>
<li><a target="_blank" href="https://www.github.com/ThakeeNathees/pocketlang/">Github</a></li>
</ul>
</div>
</div>
<!-- The toolbar below the navbar. -->
<div id="toolbar">
<div id="code-example-titles">
<div class="code-example-title" name="Simple"><h2>Simple</h2></div>
<div class="code-example-title" name="Concurrent"><h2>Concurrent</h2></div>
<div class="code-example-title" name="Object-Oriented"><h2>Object-Oriented</h2></div>
</div>
<div id="run-button">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<path fill="none" d="M0 0h24v24H0z"/>
<path fill="currentColor" d="M19.376 12.416L8.777 19.482A.5.5 0 0 1 8 19.066V4.934a.5.5 0 0 1 .777-.416l10.599 7.066a.5.5 0 0 1 0 .832z"/>
</svg>
<p>Run</p>
</div>
</div>
<!-- The Code Editor. -->
<div id="code-area">
<div id="code-editor" class="code language-ruby"></div>
<pre id="code-output" class="code"></pre>
</div>
<script async type="text/javascript" src="{{ STATIC_DIR }}wasm/pocketlang.js"></script>
<script src="{{ STATIC_DIR }}js/main.js"></script>
<script src="{{ STATIC_DIR }}js/try_online.js"></script>
</body>
</html>

View File

@ -114,7 +114,7 @@ typedef enum {
TK_AS, // as TK_AS, // as
TK_DEF, // def TK_DEF, // def
TK_NATIVE, // native (C function declaration) TK_NATIVE, // native (C function declaration)
TK_FUNCTION, // function (literal function) TK_FN, // function (literal function)
TK_END, // end TK_END, // end
TK_NULL, // null TK_NULL, // null
@ -178,7 +178,7 @@ static _Keyword _keywords[] = {
{ "as", 2, TK_AS }, { "as", 2, TK_AS },
{ "def", 3, TK_DEF }, { "def", 3, TK_DEF },
{ "native", 6, TK_NATIVE }, { "native", 6, TK_NATIVE },
{ "function", 8, TK_FUNCTION }, { "fn", 2, TK_FN },
{ "end", 3, TK_END }, { "end", 3, TK_END },
{ "null", 4, TK_NULL }, { "null", 4, TK_NULL },
{ "in", 2, TK_IN }, { "in", 2, TK_IN },
@ -407,6 +407,11 @@ typedef struct sParser {
ForwardName forwards[MAX_FORWARD_NAMES]; ForwardName forwards[MAX_FORWARD_NAMES];
int forwards_count; int forwards_count;
// A syntax sugar to skip call parentheses. Like lua support for number of
// literals. We're doing it for literal functions for now. It'll be set to
// true before exprCall to indicate that the call paran should be skipped.
bool optional_call_paran;
bool repl_mode; bool repl_mode;
bool parsing_class; bool parsing_class;
bool need_more_lines; //< True if we need more lines in REPL mode. bool need_more_lines; //< True if we need more lines in REPL mode.
@ -528,6 +533,7 @@ static void parserInit(Parser* parser, PKVM* vm, Compiler* compiler,
parser->forwards_count = 0; parser->forwards_count = 0;
parser->repl_mode = !!(compiler->options && compiler->options->repl_mode); parser->repl_mode = !!(compiler->options && compiler->options->repl_mode);
parser->optional_call_paran = false;
parser->parsing_class = false; parser->parsing_class = false;
parser->has_errors = false; parser->has_errors = false;
parser->has_syntax_error = false; parser->has_syntax_error = false;
@ -1589,7 +1595,7 @@ GrammarRule rules[] = { // Prefix Infix Infix Precedence
/* TK_AS */ NO_RULE, /* TK_AS */ NO_RULE,
/* TK_DEF */ NO_RULE, /* TK_DEF */ NO_RULE,
/* TK_EXTERN */ NO_RULE, /* TK_EXTERN */ NO_RULE,
/* TK_FUNCTION */ { exprFunction, NULL, NO_INFIX }, /* TK_FN */ { exprFunction, NULL, NO_INFIX },
/* TK_END */ NO_RULE, /* TK_END */ NO_RULE,
/* TK_NULL */ { exprValue, NULL, NO_INFIX }, /* TK_NULL */ { exprValue, NULL, NO_INFIX },
/* TK_IN */ { NULL, exprBinaryOp, PREC_TEST }, /* TK_IN */ { NULL, exprBinaryOp, PREC_TEST },
@ -1706,6 +1712,71 @@ static void emitStoreValue(Compiler* compiler, NameDefnType type, int index) {
} }
} }
// This function is reused between calls and method calls. if the [call_type]
// is OP_METHOD_CALL the [method] should refer a string in the module's
// constant pool, otherwise it's ignored.
static void _compileCall(Compiler* compiler, Opcode call_type, int method) {
ASSERT((call_type == OP_CALL) ||
(call_type == OP_METHOD_CALL) ||
(call_type == OP_SUPER_CALL), OOPS);
// Compile parameters.
int argc = 0;
if (compiler->parser.optional_call_paran) {
compiler->parser.optional_call_paran = false;
compileExpression(compiler);
argc = 1;
} else {
if (!match(compiler, TK_RPARAN)) {
do {
skipNewLines(compiler);
compileExpression(compiler);
skipNewLines(compiler);
argc++;
} while (match(compiler, TK_COMMA));
consume(compiler, TK_RPARAN, "Expected ')' after parameter list.");
}
}
emitOpcode(compiler, call_type);
emitByte(compiler, argc);
if ((call_type == OP_METHOD_CALL) || (call_type == OP_SUPER_CALL)) {
ASSERT_INDEX(method, (int)compiler->module->constants.count);
emitShort(compiler, method);
}
// After the call the arguments will be popped and the callable
// will be replaced with the return value.
compilerChangeStack(compiler, -argc);
}
// Like lua, we're omitting the paranthese for literals, it'll check for
// literals that can be passed for no pranthese call (a syntax sugar) and
// emit the call. Return true if such call matched. If [method] >= 0 it'll
// compile a method call otherwise a regular call.
static bool _compileOptionalParanCall(Compiler* compiler, int method) {
static TokenType tk[] = {
TK_FN,
//TK_STRING,
//TK_STRING_INTERP,
TK_ERROR, // Sentinel to stop the iteration.
};
for (int i = 0; tk[i] != TK_ERROR; i++) {
if (peek(compiler) == tk[i]) {
compiler->parser.optional_call_paran = true;
Opcode call_type = ((method >= 0) ? OP_METHOD_CALL : OP_CALL);
_compileCall(compiler, call_type, method);
return true;
}
}
return false;
}
static void exprLiteral(Compiler* compiler) { static void exprLiteral(Compiler* compiler) {
Token* value = &compiler->parser.previous; Token* value = &compiler->parser.previous;
int index = compilerAddConstant(compiler, value->value); int index = compilerAddConstant(compiler, value->value);
@ -1878,6 +1949,8 @@ static void exprName(Compiler* compiler) {
} else { } else {
emitPushValue(compiler, result.type, result.index); emitPushValue(compiler, result.type, result.index);
} }
_compileOptionalParanCall(compiler, -1);
} }
} }
@ -2016,40 +2089,6 @@ static void exprMap(Compiler* compiler) {
consume(compiler, TK_RBRACE, "Expected '}' after map elements."); consume(compiler, TK_RBRACE, "Expected '}' after map elements.");
} }
// This function is reused between calls and method calls. if the [call_type]
// is OP_METHOD_CALL the [method] should refer a string in the module's
// constant pool, otherwise it's ignored.
static void _compileCall(Compiler* compiler, Opcode call_type, int method) {
ASSERT((call_type == OP_CALL) ||
(call_type == OP_METHOD_CALL) ||
(call_type == OP_SUPER_CALL), OOPS);
// Compile parameters.
int argc = 0;
if (!match(compiler, TK_RPARAN)) {
do {
skipNewLines(compiler);
compileExpression(compiler);
skipNewLines(compiler);
argc++;
} while (match(compiler, TK_COMMA));
consume(compiler, TK_RPARAN, "Expected ')' after parameter list.");
}
emitOpcode(compiler, call_type);
emitByte(compiler, argc);
if ((call_type == OP_METHOD_CALL) || (call_type == OP_SUPER_CALL)) {
ASSERT_INDEX(method, (int)compiler->module->constants.count);
emitShort(compiler, method);
}
// After the call the arguments will be popped and the callable
// will be replaced with the return value.
compilerChangeStack(compiler, -argc);
}
static void exprCall(Compiler* compiler) { static void exprCall(Compiler* compiler) {
_compileCall(compiler, OP_CALL, -1); _compileCall(compiler, OP_CALL, -1);
} }
@ -2070,6 +2109,9 @@ static void exprAttrib(Compiler* compiler) {
return; return;
} }
// Check if it's a method call without paranthese.
if (_compileOptionalParanCall(compiler, index)) return;
if (compiler->l_value && matchAssignment(compiler)) { if (compiler->l_value && matchAssignment(compiler)) {
TokenType assignment = compiler->parser.previous.type; TokenType assignment = compiler->parser.previous.type;
skipNewLines(compiler); skipNewLines(compiler);

View File

@ -818,6 +818,26 @@ static void _ctorFiber(PKVM* vm) {
#define SELF (vm->fiber->self) #define SELF (vm->fiber->self)
DEF(_numberTimes,
"Number.times(f:fn)\n"
"Iterate the function [f] n times. Here n is the integral value of the "
"number. If the number is not an integer the floor value will be taken.") {
ASSERT(IS_NUM(SELF), OOPS);
double n = AS_NUM(SELF);
Closure* closure;
if (!validateArgClosure(vm, 1, &closure)) return;
for (int64_t i = 0; i < n; i++) {
Var _i = VAR_NUM((double)i);
PkResult result = vmRunFunction(vm, closure, 1, &_i, NULL);
if (result != PK_RESULT_SUCCESS) break;
}
RET(VAR_NULL);
}
DEF(_listAppend, DEF(_listAppend,
"List.append(value:var) -> List\n" "List.append(value:var) -> List\n"
"Append the [value] to the list and return the list.") { "Append the [value] to the list and return the list.") {
@ -914,9 +934,10 @@ static void initializePrimitiveClasses(PKVM* vm) {
vmPopTempRef(vm); /* fn. */ \ vmPopTempRef(vm); /* fn. */ \
} while (false) } while (false)
ADD_METHOD(PK_LIST, "append", _listAppend, 1); ADD_METHOD(PK_NUMBER, "times", _numberTimes, 1);
ADD_METHOD(PK_FIBER, "run", _fiberRun, -1); ADD_METHOD(PK_LIST, "append", _listAppend, 1);
ADD_METHOD(PK_FIBER, "resume", _fiberResume, -1); ADD_METHOD(PK_FIBER, "run", _fiberRun, -1);
ADD_METHOD(PK_FIBER, "resume", _fiberResume, -1);
#undef ADD_METHOD #undef ADD_METHOD
} }
@ -1346,8 +1367,7 @@ Var varGetAttrib(PKVM* vm, Var on, String* attrib) {
varTypeName(on), attrib->data)) varTypeName(on), attrib->data))
if (!IS_OBJ(on)) { if (!IS_OBJ(on)) {
VM_SET_ERROR(vm, stringFormat(vm, "$ type is not subscriptable.", ERR_NO_ATTRIB(vm, on, attrib);
varTypeName(on)));
return VAR_NULL; return VAR_NULL;
} }
@ -1501,8 +1521,7 @@ do { \
} while (false) } while (false)
if (!IS_OBJ(on)) { if (!IS_OBJ(on)) {
VM_SET_ERROR(vm, stringFormat(vm, "$ type is not subscriptable.", ERR_NO_ATTRIB(vm, on, attrib);
varTypeName(on)));
return; return;
} }

View File

@ -18,7 +18,7 @@ assert(0xa1b2c3 == 10597059 and 0xff == 255)
assert(0xffffffffffffffff == 18446744073709551615) assert(0xffffffffffffffff == 18446744073709551615)
## Lists test. ## Lists test.
l1 = [1, false, null, function print('hello') end, true] l1 = [1, false, null, fn print('hello') end, true]
assert(l1[4]) assert(l1[4])
l1[3] = null; assert(!l1[3]) l1[3] = null; assert(!l1[3])
l1 = [] + [] ; assert(l1.length == 0) l1 = [] + [] ; assert(l1.length == 0)
@ -48,7 +48,7 @@ assert(str(42) == '42')
## Logical statement test ## Logical statement test
val = 0; a = false; b = true val = 0; a = false; b = true
get_true = function return true end get_true = fn return true end
if a and b then assert(false) end if a and b then assert(false) end
if a or b then val = 42 else assert(false) end assert(val == 42) if a or b then val = 42 else assert(false) end assert(val == 42)
if get_true() or false then val = 12 end assert(val == 12) if get_true() or false then val = 12 end assert(val == 12)

View File

@ -2,15 +2,15 @@
## Simple upvalue. ## Simple upvalue.
def f1 def f1
local = "foo" local = "foo"
return function return fn
return local return local
end end
end end
assert(f1()() == "foo") assert(f1()() == "foo")
def add3(x) def add3(x)
return function(y) return fn(y)
return function(z) return fn(z)
return x + y + z return x + y + z
end end
end end
@ -21,11 +21,11 @@ assert(add3(7)(6)(4) == 17);
## Upvalue external to the inner function. ## Upvalue external to the inner function.
def f2 def f2
local = "bar" local = "bar"
return function return fn
fn = function f = fn
return local return local
end end
return fn return f
end end
end end
assert(f2()()() == "bar") assert(f2()()() == "bar")
@ -33,10 +33,10 @@ assert(f2()()() == "bar")
## Check if upvalues are shared between closures. ## Check if upvalues are shared between closures.
def f3 def f3
local = "baz" local = "baz"
_fn1 = function(x) _fn1 = fn(x)
local = x local = x
end end
_fn2 = function _fn2 = fn
return local return local
end end
return [_fn1, _fn2] return [_fn1, _fn2]
@ -52,7 +52,7 @@ def f4
j = i ## 'i' is shared, but 'j' doesn't j = i ## 'i' is shared, but 'j' doesn't
list_append( list_append(
a, a,
function fn
return x + j return x + j
end end
) )
@ -66,13 +66,13 @@ assert(a[1]() == 21)
def f5 def f5
l1 = 12 l1 = 12
return function ## c1 return fn ## c1
l2 = 34 l2 = 34
return function ## c2 return fn ## c2
l3 = 56 l3 = 56
return function ## c3 return fn ## c3
return function ## c4 return fn ## c4
return function ## c5 return fn ## c5
return l1 + l2 + l3 return l1 + l2 + l3
end end
end end

View File

@ -1,7 +1,7 @@
## If statements. ## If statements.
variable = null ## Will be changed by the control flow. variable = null ## Will be changed by the control flow.
unreachable = function assert(false, 'Unreachable') end unreachable = fn assert(false, 'Unreachable') end
if true then variable = 42 else unreachable() end if true then variable = 42 else unreachable() end
assert(variable == 42, 'If statement failed.') assert(variable == 42, 'If statement failed.')

View File

@ -23,11 +23,11 @@ assert([1, 2, 3].length == 3)
## Function ## Function
assert(print.arity == -1) assert(print.arity == -1)
assert(hex.arity == 1) assert(hex.arity == 1)
assert(function(a, b)end .arity == 2) assert(fn(a, b)end .arity == 2)
assert(print.name == "print") assert(print.name == "print")
def fn(p1, p2, p3) end def foo(p1, p2, p3) end
assert(fn.name == "fn") assert(foo.name == "foo")
assert(fn.arity == 3) assert(foo.arity == 3)
## String functions ## String functions
assert(str_sub('c programming', 2, 11) == 'programming') assert(str_sub('c programming', 2, 11) == 'programming')

View File

@ -9,7 +9,7 @@ assert(f3('a', 'b', 'c', 'd') == 'c')
## Local variables of inner funcions. ## Local variables of inner funcions.
def f4 def f4
l1 = 3.14 l1 = 3.14
f5 = function f5 = fn
l2 = 42 l2 = 42
return l2 return l2
end end