From a83aa9438e38252d13d74b22ffe9bd47f8dc1030 Mon Sep 17 00:00:00 2001 From: Thakee Nathees Date: Sat, 7 May 2022 11:18:06 +0530 Subject: [PATCH] documentations are refactored function keyword changed back to fn --- cli/modules/std_math.c | 2 +- docs/.nojekyll | 0 docs/404.html | 46 ++ docs/GettingStarted/LanguageManual.md | 395 ++++++++++++++++++ docs/README.md | 63 +++ docs/Reference/Math.md | 29 ++ docs/Reference/Path.md | 23 + docs/TODO.txt | 63 --- docs/_sidebar.md | 8 + docs/generate.py | 288 ------------- docs/index.html | 66 +++ docs/markdown/Api-Docs/Fiber.md | 96 ----- docs/markdown/Api-Docs/Module.md | 80 ---- docs/markdown/Reference/Build-From-Source.md | 40 -- docs/markdown/Reference/Cheat-Sheet.md | 104 ----- docs/markdown/Reference/Getting-Started.md | 29 -- docs/markdown/Reference/Installation.md | 13 - docs/static/css/docs.css | 279 ------------- docs/static/css/home.css | 209 --------- docs/static/css/navbar.css | 42 -- docs/static/css/style.css | 101 ----- docs/static/css/try_online.css | 161 ------- .../highlight.js/github-dark-dimmed.min.css | 11 + docs/static/highlight.js/highlight.min.js | 2 +- .../highlight.js/stackoverflow-light.min.css | 13 + docs/static/highlight.js/theme_dark.css | 74 ---- docs/static/highlight.js/theme_docs.css | 74 ---- docs/static/img/concurrent.svg | 57 --- docs/static/img/favicon.svg | 51 --- docs/static/img/gc.svg | 73 ---- docs/static/img/gear.svg | 57 --- docs/static/img/pocketlang.svg | 86 ---- docs/static/img/repl.svg | 47 --- docs/static/js/docs.js | 12 - docs/static/js/home.js | 8 - docs/static/js/main.js | 10 - docs/static/js/try_online.js | 100 ----- docs/static/main.js | 50 +++ docs/static/prism/prism.css | 143 ------- docs/static/prism/prism.js | 18 - docs/static/style.css | 50 +++ docs/templates/docs.html | 71 ---- docs/templates/index.html | 77 ---- docs/templates/try-online.html | 60 --- src/pk_compiler.c | 116 +++-- src/pk_core.c | 33 +- tests/lang/basics.pk | 4 +- tests/lang/closure.pk | 28 +- tests/lang/controlflow.pk | 2 +- tests/lang/core.pk | 8 +- tests/lang/functions.pk | 2 +- 51 files changed, 883 insertions(+), 2591 deletions(-) create mode 100644 docs/.nojekyll create mode 100644 docs/404.html create mode 100644 docs/GettingStarted/LanguageManual.md create mode 100644 docs/README.md create mode 100644 docs/Reference/Math.md create mode 100644 docs/Reference/Path.md delete mode 100644 docs/TODO.txt create mode 100644 docs/_sidebar.md delete mode 100644 docs/generate.py create mode 100644 docs/index.html delete mode 100644 docs/markdown/Api-Docs/Fiber.md delete mode 100644 docs/markdown/Api-Docs/Module.md delete mode 100644 docs/markdown/Reference/Build-From-Source.md delete mode 100644 docs/markdown/Reference/Cheat-Sheet.md delete mode 100644 docs/markdown/Reference/Getting-Started.md delete mode 100644 docs/markdown/Reference/Installation.md delete mode 100644 docs/static/css/docs.css delete mode 100644 docs/static/css/home.css delete mode 100644 docs/static/css/navbar.css delete mode 100644 docs/static/css/style.css delete mode 100644 docs/static/css/try_online.css create mode 100644 docs/static/highlight.js/github-dark-dimmed.min.css create mode 100644 docs/static/highlight.js/stackoverflow-light.min.css delete mode 100644 docs/static/highlight.js/theme_dark.css delete mode 100644 docs/static/highlight.js/theme_docs.css delete mode 100644 docs/static/img/concurrent.svg delete mode 100644 docs/static/img/favicon.svg delete mode 100644 docs/static/img/gc.svg delete mode 100644 docs/static/img/gear.svg delete mode 100644 docs/static/img/pocketlang.svg delete mode 100644 docs/static/img/repl.svg delete mode 100644 docs/static/js/docs.js delete mode 100644 docs/static/js/home.js delete mode 100644 docs/static/js/main.js delete mode 100644 docs/static/js/try_online.js create mode 100644 docs/static/main.js delete mode 100644 docs/static/prism/prism.css delete mode 100644 docs/static/prism/prism.js create mode 100644 docs/static/style.css delete mode 100644 docs/templates/docs.html delete mode 100644 docs/templates/index.html delete mode 100644 docs/templates/try-online.html diff --git a/cli/modules/std_math.c b/cli/modules/std_math.c index 7afe746..1247f52 100644 --- a/cli/modules/std_math.c +++ b/cli/modules/std_math.c @@ -32,7 +32,7 @@ DEF(stdMathCeil, } DEF(stdMathPow, - "pow(value:num) -> num\n") { + "pow(a:num, b:num) -> num\n") { double num, ex; if (!pkValidateSlotNumber(vm, 1, &num)) return; diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docs/404.html b/docs/404.html new file mode 100644 index 0000000..7539307 --- /dev/null +++ b/docs/404.html @@ -0,0 +1,46 @@ + + + + + + + + pocketlang + + + + +
+
+ print('Page under construction') +
+
+ + + \ No newline at end of file diff --git a/docs/GettingStarted/LanguageManual.md b/docs/GettingStarted/LanguageManual.md new file mode 100644 index 0000000..a80ef0a --- /dev/null +++ b/docs/GettingStarted/LanguageManual.md @@ -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. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..078c2e9 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,63 @@ + +

+Pocketlang v0.1.0 +

+ +

+Pocketlang is a lightweight & fast object oriented programming language designed for embedding and +scripting. Including the compiler, bytecode VM and runtime it's a standalone executable +which is less than 300KB and the language itself can be compiled in less than +4s without any external dependencies. +

+ +
+ Try Online + GitHub +
+ +
+ +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. diff --git a/docs/Reference/Math.md b/docs/Reference/Math.md new file mode 100644 index 0000000..39138ce --- /dev/null +++ b/docs/Reference/Math.md @@ -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 +``` diff --git a/docs/Reference/Path.md b/docs/Reference/Path.md new file mode 100644 index 0000000..da38b89 --- /dev/null +++ b/docs/Reference/Path.md @@ -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 +``` diff --git a/docs/TODO.txt b/docs/TODO.txt deleted file mode 100644 index 4c634ad..0000000 --- a/docs/TODO.txt +++ /dev/null @@ -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. diff --git a/docs/_sidebar.md b/docs/_sidebar.md new file mode 100644 index 0000000..85f1aed --- /dev/null +++ b/docs/_sidebar.md @@ -0,0 +1,8 @@ + +* Getting Started + * [Home](/) + * [Language Manual](/GettingStarted/LanguageManual.md) + +* Library Reference + * [math](/Reference/Math.md) + * [path](/Reference/Path.md) diff --git a/docs/generate.py b/docs/generate.py deleted file mode 100644 index 8617e86..0000000 --- a/docs/generate.py +++ /dev/null @@ -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('
') - write(' ') - write(f'

{feature_name}

') - write(f'

{feature["desc"]}

') - write(f' Learn more') - write('
') - 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'

{topic} #

\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'
\n'
-      in_code = True
-
-    ## End of codeblock.
-    elif in_code and stripped_line.startswith('```'):
-      md_new += '
\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('
  • ') - write(' ') - write(' ') - write('
  • ') - return gen - -## Generate table of content entries for the page. -def generate_toc_entries(topics): - gen = "" - for topic in topics: - gen += f'
  • ' - gen += f'{topic.replace("-", " ")}' - gen += '
  • \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() - diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..8a3bd31 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,66 @@ + + + + + Pocketlag Docs + + + + + + + + + + + + + + +
    + + + + + + + + + + + diff --git a/docs/markdown/Api-Docs/Fiber.md b/docs/markdown/Api-Docs/Fiber.md deleted file mode 100644 index ed9c357..0000000 --- a/docs/markdown/Api-Docs/Fiber.md +++ /dev/null @@ -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) -``` diff --git a/docs/markdown/Api-Docs/Module.md b/docs/markdown/Api-Docs/Module.md deleted file mode 100644 index f86ee6a..0000000 --- a/docs/markdown/Api-Docs/Module.md +++ /dev/null @@ -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' -``` diff --git a/docs/markdown/Reference/Build-From-Source.md b/docs/markdown/Reference/Build-From-Source.md deleted file mode 100644 index d19b2e0..0000000 --- a/docs/markdown/Reference/Build-From-Source.md +++ /dev/null @@ -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). diff --git a/docs/markdown/Reference/Cheat-Sheet.md b/docs/markdown/Reference/Cheat-Sheet.md deleted file mode 100644 index cfe7698..0000000 --- a/docs/markdown/Reference/Cheat-Sheet.md +++ /dev/null @@ -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) -``` diff --git a/docs/markdown/Reference/Getting-Started.md b/docs/markdown/Reference/Getting-Started.md deleted file mode 100644 index fc07dad..0000000 --- a/docs/markdown/Reference/Getting-Started.md +++ /dev/null @@ -1,29 +0,0 @@ - - -PLEASE NOTE THAT THIS PAGE IS UNDER CONSTRUCTION AND EVERYTHING IS PLACEHOLDER. - - -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) - - diff --git a/docs/markdown/Reference/Installation.md b/docs/markdown/Reference/Installation.md deleted file mode 100644 index b7fda1a..0000000 --- a/docs/markdown/Reference/Installation.md +++ /dev/null @@ -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 -``` diff --git a/docs/static/css/docs.css b/docs/static/css/docs.css deleted file mode 100644 index 54d6473..0000000 --- a/docs/static/css/docs.css +++ /dev/null @@ -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 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; - } -} \ No newline at end of file diff --git a/docs/static/css/home.css b/docs/static/css/home.css deleted file mode 100644 index cc270c1..0000000 --- a/docs/static/css/home.css +++ /dev/null @@ -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; - } - -} \ No newline at end of file diff --git a/docs/static/css/navbar.css b/docs/static/css/navbar.css deleted file mode 100644 index 007498a..0000000 --- a/docs/static/css/navbar.css +++ /dev/null @@ -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; - } - -} \ No newline at end of file diff --git a/docs/static/css/style.css b/docs/static/css/style.css deleted file mode 100644 index 7a9b39d..0000000 --- a/docs/static/css/style.css +++ /dev/null @@ -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; -} diff --git a/docs/static/css/try_online.css b/docs/static/css/try_online.css deleted file mode 100644 index e494ad0..0000000 --- a/docs/static/css/try_online.css +++ /dev/null @@ -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; - } -} diff --git a/docs/static/highlight.js/github-dark-dimmed.min.css b/docs/static/highlight.js/github-dark-dimmed.min.css new file mode 100644 index 0000000..b1ec282 --- /dev/null +++ b/docs/static/highlight.js/github-dark-dimmed.min.css @@ -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} \ No newline at end of file diff --git a/docs/static/highlight.js/highlight.min.js b/docs/static/highlight.js/highlight.min.js index 7205df2..8a4f399 100644 --- a/docs/static/highlight.js/highlight.min.js +++ b/docs/static/highlight.js/highlight.min.js @@ -924,7 +924,7 @@ contains:[{begin:/\\./}]}]}},grmr_ruby:e=>{ const n=e.regex,t="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",a={ /* 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__"}, i={className:"doctag", begin:"@[A-Za-z]+"},r={begin:"#<",end:">"},s=[e.COMMENT("#","$",{contains:[i] diff --git a/docs/static/highlight.js/stackoverflow-light.min.css b/docs/static/highlight.js/stackoverflow-light.min.css new file mode 100644 index 0000000..c36d63d --- /dev/null +++ b/docs/static/highlight.js/stackoverflow-light.min.css @@ -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} \ No newline at end of file diff --git a/docs/static/highlight.js/theme_dark.css b/docs/static/highlight.js/theme_dark.css deleted file mode 100644 index 9133e98..0000000 --- a/docs/static/highlight.js/theme_dark.css +++ /dev/null @@ -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 -} diff --git a/docs/static/highlight.js/theme_docs.css b/docs/static/highlight.js/theme_docs.css deleted file mode 100644 index 2d14d3b..0000000 --- a/docs/static/highlight.js/theme_docs.css +++ /dev/null @@ -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 -} diff --git a/docs/static/img/concurrent.svg b/docs/static/img/concurrent.svg deleted file mode 100644 index f3192a9..0000000 --- a/docs/static/img/concurrent.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - diff --git a/docs/static/img/favicon.svg b/docs/static/img/favicon.svg deleted file mode 100644 index 5009498..0000000 --- a/docs/static/img/favicon.svg +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - diff --git a/docs/static/img/gc.svg b/docs/static/img/gc.svg deleted file mode 100644 index 7d00910..0000000 --- a/docs/static/img/gc.svg +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/docs/static/img/gear.svg b/docs/static/img/gear.svg deleted file mode 100644 index ede4112..0000000 --- a/docs/static/img/gear.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - diff --git a/docs/static/img/pocketlang.svg b/docs/static/img/pocketlang.svg deleted file mode 100644 index 3877ac1..0000000 --- a/docs/static/img/pocketlang.svg +++ /dev/null @@ -1,86 +0,0 @@ - - - - diff --git a/docs/static/img/repl.svg b/docs/static/img/repl.svg deleted file mode 100644 index 09c5042..0000000 --- a/docs/static/img/repl.svg +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - diff --git a/docs/static/js/docs.js b/docs/static/js/docs.js deleted file mode 100644 index 2d62eb4..0000000 --- a/docs/static/js/docs.js +++ /dev/null @@ -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"); - } -}); diff --git a/docs/static/js/home.js b/docs/static/js/home.js deleted file mode 100644 index be1847c..0000000 --- a/docs/static/js/home.js +++ /dev/null @@ -1,8 +0,0 @@ - -window.addEventListener('scroll', function() { - if (window.scrollY > 30) { - $("#navbar").classList.add("stick"); - } else { - $("#navbar").classList.remove("stick"); - } -}); diff --git a/docs/static/js/main.js b/docs/static/js/main.js deleted file mode 100644 index e9f2b6c..0000000 --- a/docs/static/js/main.js +++ /dev/null @@ -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); - }); -}); diff --git a/docs/static/js/try_online.js b/docs/static/js/try_online.js deleted file mode 100644 index 825f322..0000000 --- a/docs/static/js/try_online.js +++ /dev/null @@ -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); - } -} diff --git a/docs/static/main.js b/docs/static/main.js new file mode 100644 index 0000000..68b9a65 --- /dev/null +++ b/docs/static/main.js @@ -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 = ``; +const SUN = ``; + +function createThemeButton() { + let div = document.createElement('button'); + div.innerHTML = ""; + div.innerHTML += ``; + div.innerHTML += ``; + 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(); + } +} diff --git a/docs/static/prism/prism.css b/docs/static/prism/prism.css deleted file mode 100644 index 811d3ff..0000000 --- a/docs/static/prism/prism.css +++ /dev/null @@ -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; -} - diff --git a/docs/static/prism/prism.js b/docs/static/prism/prism.js deleted file mode 100644 index 88c13e2..0000000 --- a/docs/static/prism/prism.js +++ /dev/null @@ -1,18 +0,0 @@ -/* PrismJS 1.23.0 -https://prismjs.com/download.html#themes=prism&languages=clike+ruby */ - -/** - * This file is modified by http://github.com/ThakeeNathees/. - * To highlight pocketlang (https://github.com/ThakeeNathees/pocketlang/) which is similar to ruby. - */ - - -var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var c=/\blang(?:uage)?-([\w-]+)\b/i,n=0,e={},M={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof W?new W(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=l.reach);y+=m.value.length,m=m.next){var b=m.value;if(t.length>n.length)return;if(!(b instanceof W)){var k,x=1;if(h){if(!(k=z(v,y,n,f)))break;var w=k.index,A=k.index+k[0].length,P=y;for(P+=m.value.length;P<=w;)m=m.next,P+=m.value.length;if(P-=m.value.length,y=P,m.value instanceof W)continue;for(var E=m;E!==t.tail&&(Pl.reach&&(l.reach=N);var j=m.prev;O&&(j=I(t,j,O),y+=O.length),q(t,j,x);var C=new W(o,g?M.tokenize(S,g):S,d,S);if(m=I(t,j,C),L&&I(t,m,L),1l.reach&&(l.reach=_.reach)}}}}}}(e,a,n,a.head,0),function(e){var n=[],t=e.head.next;for(;t!==e.tail;)n.push(t.value),t=t.next;return n}(a)},hooks:{all:{},add:function(e,n){var t=M.hooks.all;t[e]=t[e]||[],t[e].push(n)},run:function(e,n){var t=M.hooks.all[e];if(t&&t.length)for(var r,a=0;r=t[a++];)r(n)}},Token:W};function W(e,n,t,r){this.type=e,this.content=n,this.alias=t,this.length=0|(r||"").length}function z(e,n,t,r){e.lastIndex=n;var a=e.exec(t);if(a&&r&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function i(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function I(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function q(e,n,t){for(var r=n.next,a=0;a"+a.content+""},!u.document)return u.addEventListener&&(M.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),t=n.language,r=n.code,a=n.immediateClose;u.postMessage(M.highlight(r,M.languages[t],t)),a&&u.close()},!1)),M;var t=M.util.currentScript();function r(){M.manual||M.highlightAll()}if(t&&(M.filename=t.src,t.hasAttribute("data-manual")&&(M.manual=!0)),!M.manual){var a=document.readyState;"loading"===a||"interactive"===a&&t&&t.defer?document.addEventListener("DOMContentLoaded",r):window.requestAnimationFrame?window.requestAnimationFrame(r):window.setTimeout(r,16)}return M}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); -Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/}; -!function(e){e.languages.ruby=e.languages.extend("clike",{comment:[/#.*/,{pattern:/^=begin\s[\s\S]*?^=end/m,greedy:!0}],"class-name":{pattern:/(\b(?:class)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}}, - -// The below line was changed to the line below it. -// keyword:/\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/}); -keyword:/\b(?:and|break|class|def|do|else|elsif|end|for|if|in|module|not|or|raise|return|self|then|throw|while|yield|null|from|import|as|func|native|continue)\b/}); - -var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.languages.ruby}};delete e.languages.ruby.function,e.languages.insertBefore("ruby","keyword",{regex:[{pattern:RegExp("%r(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","\\((?:[^()\\\\]|\\\\[^])*\\)","\\{(?:[^#{}\\\\]|#(?:\\{[^}]+\\})?|\\\\[^])*\\}","\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\]","<(?:[^<>\\\\]|\\\\[^])*>"].join("|")+")[egimnosux]{0,6}"),greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:n}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:{pattern:/(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,lookbehind:!0},"method-definition":{pattern:/(\bdef\s+)[\w.]+/,lookbehind:!0,inside:{function:/\w+$/,rest:e.languages.ruby}}}),e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|Fixnum|Float|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z]\w*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:RegExp("%[qQiIwWxs]?(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","\\((?:[^()\\\\]|\\\\[^])*\\)","\\{(?:[^#{}\\\\]|#(?:\\{[^}]+\\})?|\\\\[^])*\\}","\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\]","<(?:[^<>\\\\]|\\\\[^])*>"].join("|")+")"),greedy:!0,inside:{interpolation:n}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:n}}],e.languages.rb=e.languages.ruby}(Prism); diff --git a/docs/static/style.css b/docs/static/style.css new file mode 100644 index 0000000..5af75bc --- /dev/null +++ b/docs/static/style.css @@ -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; +} diff --git a/docs/templates/docs.html b/docs/templates/docs.html deleted file mode 100644 index b3c87b4..0000000 --- a/docs/templates/docs.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - Docs - pocketlang - - - - - - - - -
    - - -
    -

    {{ PAGE_TITLE }} #

    - - {{ PAGE_CONTENT }} - - -
    - - -
    -

    In this page

    -
      - {{ TOC_ENTRIES }} -
    -
    - -
    - - - - - - diff --git a/docs/templates/index.html b/docs/templates/index.html deleted file mode 100644 index bad2629..0000000 --- a/docs/templates/index.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - Pocketlang - - - - - - - -
    - - -
    -
    -

    Pocketlang is a small fast and friendly language

    -

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

    - -
    - -
    - - - -
    -

    What pocketlang looks like?

    -

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

    -
    {{ WHAT_IT_LOOKS_LIKE }}
    -
    - -
    -
    - {{ POCKET_FEATURES }} -
    -
    - - - -
    - - - - - - diff --git a/docs/templates/try-online.html b/docs/templates/try-online.html deleted file mode 100644 index f3f00c9..0000000 --- a/docs/templates/try-online.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - Pocketlang - Try Online - - - - - - - - -
    -
    -

    Simple

    -

    Concurrent

    -

    Object-Oriented

    -
    -
    - - - - -

    Run

    -
    -
    - - - -
    -
    -
    
    -  
    - - - - - - - \ No newline at end of file diff --git a/src/pk_compiler.c b/src/pk_compiler.c index dadeba9..2ebd6e4 100644 --- a/src/pk_compiler.c +++ b/src/pk_compiler.c @@ -114,7 +114,7 @@ typedef enum { TK_AS, // as TK_DEF, // def TK_NATIVE, // native (C function declaration) - TK_FUNCTION, // function (literal function) + TK_FN, // function (literal function) TK_END, // end TK_NULL, // null @@ -178,7 +178,7 @@ static _Keyword _keywords[] = { { "as", 2, TK_AS }, { "def", 3, TK_DEF }, { "native", 6, TK_NATIVE }, - { "function", 8, TK_FUNCTION }, + { "fn", 2, TK_FN }, { "end", 3, TK_END }, { "null", 4, TK_NULL }, { "in", 2, TK_IN }, @@ -407,6 +407,11 @@ typedef struct sParser { ForwardName forwards[MAX_FORWARD_NAMES]; 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 parsing_class; 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->repl_mode = !!(compiler->options && compiler->options->repl_mode); + parser->optional_call_paran = false; parser->parsing_class = false; parser->has_errors = false; parser->has_syntax_error = false; @@ -1589,7 +1595,7 @@ GrammarRule rules[] = { // Prefix Infix Infix Precedence /* TK_AS */ NO_RULE, /* TK_DEF */ NO_RULE, /* TK_EXTERN */ NO_RULE, - /* TK_FUNCTION */ { exprFunction, NULL, NO_INFIX }, + /* TK_FN */ { exprFunction, NULL, NO_INFIX }, /* TK_END */ NO_RULE, /* TK_NULL */ { exprValue, NULL, NO_INFIX }, /* 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) { Token* value = &compiler->parser.previous; int index = compilerAddConstant(compiler, value->value); @@ -1878,6 +1949,8 @@ static void exprName(Compiler* compiler) { } else { 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."); } -// 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) { _compileCall(compiler, OP_CALL, -1); } @@ -2070,6 +2109,9 @@ static void exprAttrib(Compiler* compiler) { return; } + // Check if it's a method call without paranthese. + if (_compileOptionalParanCall(compiler, index)) return; + if (compiler->l_value && matchAssignment(compiler)) { TokenType assignment = compiler->parser.previous.type; skipNewLines(compiler); diff --git a/src/pk_core.c b/src/pk_core.c index 508dfbd..ac450a2 100644 --- a/src/pk_core.c +++ b/src/pk_core.c @@ -818,6 +818,26 @@ static void _ctorFiber(PKVM* vm) { #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, "List.append(value:var) -> List\n" "Append the [value] to the list and return the list.") { @@ -914,9 +934,10 @@ static void initializePrimitiveClasses(PKVM* vm) { vmPopTempRef(vm); /* fn. */ \ } while (false) - ADD_METHOD(PK_LIST, "append", _listAppend, 1); - ADD_METHOD(PK_FIBER, "run", _fiberRun, -1); - ADD_METHOD(PK_FIBER, "resume", _fiberResume, -1); + ADD_METHOD(PK_NUMBER, "times", _numberTimes, 1); + ADD_METHOD(PK_LIST, "append", _listAppend, 1); + ADD_METHOD(PK_FIBER, "run", _fiberRun, -1); + ADD_METHOD(PK_FIBER, "resume", _fiberResume, -1); #undef ADD_METHOD } @@ -1346,8 +1367,7 @@ Var varGetAttrib(PKVM* vm, Var on, String* attrib) { varTypeName(on), attrib->data)) if (!IS_OBJ(on)) { - VM_SET_ERROR(vm, stringFormat(vm, "$ type is not subscriptable.", - varTypeName(on))); + ERR_NO_ATTRIB(vm, on, attrib); return VAR_NULL; } @@ -1501,8 +1521,7 @@ do { \ } while (false) if (!IS_OBJ(on)) { - VM_SET_ERROR(vm, stringFormat(vm, "$ type is not subscriptable.", - varTypeName(on))); + ERR_NO_ATTRIB(vm, on, attrib); return; } diff --git a/tests/lang/basics.pk b/tests/lang/basics.pk index 2f316b8..445f182 100644 --- a/tests/lang/basics.pk +++ b/tests/lang/basics.pk @@ -18,7 +18,7 @@ assert(0xa1b2c3 == 10597059 and 0xff == 255) assert(0xffffffffffffffff == 18446744073709551615) ## Lists test. -l1 = [1, false, null, function print('hello') end, true] +l1 = [1, false, null, fn print('hello') end, true] assert(l1[4]) l1[3] = null; assert(!l1[3]) l1 = [] + [] ; assert(l1.length == 0) @@ -48,7 +48,7 @@ assert(str(42) == '42') ## Logical statement test 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 or b then val = 42 else assert(false) end assert(val == 42) if get_true() or false then val = 12 end assert(val == 12) diff --git a/tests/lang/closure.pk b/tests/lang/closure.pk index ea61270..bb808af 100644 --- a/tests/lang/closure.pk +++ b/tests/lang/closure.pk @@ -2,15 +2,15 @@ ## Simple upvalue. def f1 local = "foo" - return function + return fn return local end end assert(f1()() == "foo") def add3(x) - return function(y) - return function(z) + return fn(y) + return fn(z) return x + y + z end end @@ -21,11 +21,11 @@ assert(add3(7)(6)(4) == 17); ## Upvalue external to the inner function. def f2 local = "bar" - return function - fn = function + return fn + f = fn return local end - return fn + return f end end assert(f2()()() == "bar") @@ -33,10 +33,10 @@ assert(f2()()() == "bar") ## Check if upvalues are shared between closures. def f3 local = "baz" - _fn1 = function(x) + _fn1 = fn(x) local = x end - _fn2 = function + _fn2 = fn return local end return [_fn1, _fn2] @@ -52,7 +52,7 @@ def f4 j = i ## 'i' is shared, but 'j' doesn't list_append( a, - function + fn return x + j end ) @@ -66,13 +66,13 @@ assert(a[1]() == 21) def f5 l1 = 12 - return function ## c1 + return fn ## c1 l2 = 34 - return function ## c2 + return fn ## c2 l3 = 56 - return function ## c3 - return function ## c4 - return function ## c5 + return fn ## c3 + return fn ## c4 + return fn ## c5 return l1 + l2 + l3 end end diff --git a/tests/lang/controlflow.pk b/tests/lang/controlflow.pk index b8e5004..79cde3f 100644 --- a/tests/lang/controlflow.pk +++ b/tests/lang/controlflow.pk @@ -1,7 +1,7 @@ ## If statements. 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 assert(variable == 42, 'If statement failed.') diff --git a/tests/lang/core.pk b/tests/lang/core.pk index 1089351..a0913f6 100644 --- a/tests/lang/core.pk +++ b/tests/lang/core.pk @@ -23,11 +23,11 @@ assert([1, 2, 3].length == 3) ## Function assert(print.arity == -1) assert(hex.arity == 1) -assert(function(a, b)end .arity == 2) +assert(fn(a, b)end .arity == 2) assert(print.name == "print") -def fn(p1, p2, p3) end -assert(fn.name == "fn") -assert(fn.arity == 3) +def foo(p1, p2, p3) end +assert(foo.name == "foo") +assert(foo.arity == 3) ## String functions assert(str_sub('c programming', 2, 11) == 'programming') diff --git a/tests/lang/functions.pk b/tests/lang/functions.pk index 4794864..03256e7 100644 --- a/tests/lang/functions.pk +++ b/tests/lang/functions.pk @@ -9,7 +9,7 @@ assert(f3('a', 'b', 'c', 'd') == 'c') ## Local variables of inner funcions. def f4 l1 = 3.14 - f5 = function + f5 = fn l2 = 42 return l2 end