A small and fast programming language.

Overview

Pocketlang is a small (~3000 semicolons) and fast functional language written in C. It's syntactically similar to Ruby and it can be learned within 15 minutes. Including the compiler, bytecode VM and runtime, it's a standalone executable with zero external dependencies just as it's self descriptive name. The pocketlang VM can be embedded in another hosting program very easily.

Wren Language and their wonderful book Crafting Interpreters were used as a reference to write this language.

What pocketlang 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

Try It Now

You can try pocketlang on your browser. It's a WebAssembly build of the VM compiled using emscripten. Note that in the webassembly version of the language, some features (input, file handling, relative import, etc.) have disabled, has limited memory allocations, and the stdout calls might be slower.

Documentation

The pocketlang documentation is hosted at https://thakeenathees.github.io/pocketlang/ which is built from the docs branch generated by a little python script at docs/generate.py. Note that the documentations are WIP and might not be up to date.

Performance

Pocketlang supports tail call optimization. When a function returns a call, the callee can re-use the caller's stack frame, this will optimize memory from O(n) to O(1) and for tail recursive it'll completely prevent stackoverflows and yet it's faster than tco disabled.

All benchmarks below were executed on: Windows10 (64bit), ASUS N552VX, Intel Core i7-6700HQ 2.6GHz with 12GB SODIMM Ram. And the language versions are: pocketlang (pre-alpha), wren v0.3.0, python v3.7.4, ruby v2.7.2.

preformance

The source files used to run benchmarks can be found at test/benchmarks/ directory. They were executed using a small python script in the test directory.

Building From Source

It 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 make file on windows with mingw, you require make and find unix tools in your path. Which you can get from msys2 or cygwin. Run set PATH=<path-to-env/usr/bin/>;%PATH% && make, this will override the system find command with unix find for the current session, and run the make script.

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.

References

Comments
  • ^D starts an endless loop

    ^D starts an endless loop

    I wanted to exit pocket with a ^D in the terminal. Instead pocket printed out >>> in an endless loop:

    $ pocket
    PocketLang 0.1.0 (https://github.com/ThakeeNathees/pocketlang/)
    Copyright(c) 2020 - 2021 ThakeeNathees.
    Free and open source software under the terms of the MIT license.
    
    >>> ^D
    >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>>^C
    $ 
    

    This is commit 2b4d3af0a24a3952334c54fcf409e9fd9d27eaf2

    $ uname -omp
    x86_64 unknown GNU/Linux
    
    help wanted good first issue TODO 
    opened by kseistrup 13
  • [NOTICE] pocketlang is trending I guess 🚀🎉🥳

    [NOTICE] pocketlang is trending I guess 🚀🎉🥳

    This is not really an issue but a notice that the repo is trending and stars are climbing up. Good job @ThakeeNathees and thanks for giving us an opportunity to be part of this journey.

    Let's celebrate 😇 as it's now at 816 stars ⭐️

    opened by xSavitar 9
  • Introduce CLI argument parsing for pocketlang

    Introduce CLI argument parsing for pocketlang

    This patch introduces CLI argument parsing to pocketlang where basic options such as: "--help", "--version", etc are used to get some info about how to use the application on the command line.

    An attempt to fix issue #99

    enhancement 
    opened by xSavitar 7
  • Update the copyright statement in the source files.

    Update the copyright statement in the source files.

    The current copyright statement in the file headers doesn't address the pocketlang aurhtos. It should be updated like this.

    Before

    /*
     *  Copyright (c) 2020-2021 Thakee Nathees
     *  Distributed Under The MIT License
     */
    

    After

    /*
     *  Copyright (c) 2020-2021 Thakee Nathees
     *  Copyright (c) 2021 The pocketlang Authors
     *  Distributed Under The MIT License
     */
    

    And thanks for being part of this :tada:

    opened by ThakeeNathees 7
  • List addition implementation

    List addition implementation

    TODO: list addition

    Currently adding 2 lists ([1, 2] + [3, 4]) cause a crash with a TODO message. which need to be implemented. (here)

    How to implement

    List* l1, *l2 are defined above the TODO statement in the source.

    • Create a new list using newList(vm, size) function, where (initial reserved) size is the total length of l1 and l2. length of l1 = l1->elements.count
    • iterate each lists and append to the new list.
    for (uint32_t i = 0; i < l1->elements.count; i++) {
      listAppend(vm, list, l1->elements.data[i]);
    }
    
    • return the list as a var using VAR_OBJ(list) macro function.

    Finally

    Once you successfully implemented it, write some tests at tests/lang/

    good first issue 
    opened by ThakeeNathees 7
  • A quick documentation on how to run a pocketlang program locally

    A quick documentation on how to run a pocketlang program locally

    With a small factorial program written in pocketlang and executed on the terminal, this demonstrates how to execute a script on a loalhost using pocketlang binary.

    documentation 
    opened by xSavitar 6
  • Include Nodejs in Benchmarks

    Include Nodejs in Benchmarks

    Hey! It looks like you started implementing some JS for the benchmarks and stopped. There's a note in loop.js about V8's performance optimizations/benefits – I'm not sure if this deterred you from including/finishing JS or not, but I think it's still important to include them for context.

    Pocketlang doesn't have to be the fastest in a graph in order for it to be considered :) It's a cool little language and I think it has more merit than speed.

    I added the JS variants for all benchmarks and will include a sample of their results on my machine. Happy to PR the benchmark items if interested

    Node v14.15.3
    Python v3.9.5
    Pocket (master : 6d434db) -> make release
    
    benchmarks/fib
      node   0.090436s
      python 2.506929s
      pocket 1.380002s
    
    benchmarks/list
      node   0.143674s
      python 2.351552s
      pocket 0.884381s
    
    benchmarks/loop
      node   0.325279s
      python 1.946506s
      pocket 0.54898s
    
    benchmarks/primes
      node   0.143707s
      python 2.6421330000000003s
      pocket 1.400831s
    

    Again, I don't think this should be discouraging at all. It's amazing so far!

    future performance 
    opened by lukeed 5
  • add `exit` keyword

    add `exit` keyword

    Similar to Ruby having an exit keyboard would be nice. I don't think we should bring over the lack of cleanup bang variant exit! though.

    I'd be happy to implement this if some pointers (pun?) were given.

    enhancement TODO 
    opened by tsujp 5
  • lua is so fast

    lua is so fast

    my lua version is 5.3.4

    # python3 benchmarks.py                       
    ----------------------------------
     CHECKING FOR INTERPRETERS 
    ----------------------------------
    Searching for pocketlang -- found
    Searching for wren       -- not found (skipped)
    Searching for python     -- found
    Searching for ruby       -- not found (skipped)
    Searching for lua        -- found
    Searching for javascript -- not found (skipped)
    ----------------------------------
     factors 
    ----------------------------------
    pocketlang : 4.000000s
    python     : 5.265634s
    lua        : 0.600000s
    ----------------------------------
     fib 
    ----------------------------------
    pocketlang : 3.040000s
    python     : 3.029289s
    lua        : 0.950000s
    ----------------------------------
     list 
    ----------------------------------
    pocketlang : 2.880000s
    python     : 2.594415s
    lua        : 0.790000s
    ----------------------------------
     loop 
    ----------------------------------
    pocketlang : 1.230000s
    python     : 2.204718s
    lua        : 0.390000s
    ----------------------------------
     primes 
    ----------------------------------
    pocketlang : 3.740000s
    python     : 2.913168s
    lua        : 0.550000s
    
    performance 
    opened by esrrhs 4
  • Remove find dependency in Makefile

    Remove find dependency in Makefile

    Currently, our makefile depends on the find unix command which makes it harder for others to compile on windows

    Here is what they have to do

    To run make file on windows with mingw, you require make and find unix tools in your path. Which you can get from msys2 or cygwin. Run set PATH=<path-to-env/usr/bin/>;%PATH% && make, this will override the system find command with unix find for the current session, and run the make script.

    But we want the makefile to be portable and independent of the system, Remove the find from the makefile.

    help wanted good first issue portability 
    opened by ThakeeNathees 4
  • Introduce the use of function attribute (__attribute__)

    Introduce the use of function attribute (__attribute__)

    Begin using it to mark functions that have a better version such as read_line() which has a better version: readLine() that uses a byte buffer.

    Through out the code base, if we see functions that have a better version of itself, we should definitely mark it as deprecated with a meaningful deprecation message.

    In effect, the GCC compiler will through a warning level message on the console at compile time reporting these deprecated functions.

    opened by xSavitar 4
  • CudaText lexer

    CudaText lexer

    Could you make a CudaText lexer for Pocketlang? It already has lexer for various languages whose Pocketlang syntax is based on (Python, Lua, Ruby,...). It has a well documented tool to create lexer. The problem is CudaText lexer is full of regular expression and I feared regular expression so much so I have to bother you here.

    This is CudaText: https://github.com/Alexey-T/CudaText

    Document for lexer creator tool: https://github.com/Alexey-T/CudaText/issues/4515#issuecomment-1298695532

    opened by ghost 0
  • [Enhancement] add compile and eval for metaprogramming

    [Enhancement] add compile and eval for metaprogramming

    compile can compile the source code into a closure at runtime time. Example:

    message = "Metaprogramming"
    value = 12345
    
    code = "
      def test
        return $value
      end
      print('$message')
      return test()
    "
    func = compile(code)
    print(func())
    

    Output:

    Metaprogramming
    12345
    

    eval can evaluate an expression and returns the result. Example:

    message = eval("'Meta' + 'programming'")
    value = eval("123450 / 10")
    func = eval("
      fn
        print(message)
        return eval('value')
      end
    ")
    eval("print")(eval("func()"))
    

    Output:

    Metaprogramming
    12345
    
    opened by khchen 0
  • [Enhancement] conditional expression

    [Enhancement] conditional expression

    In many other language, ternary operator (:?) is the syntax for basic conditional expression. However, in some language (e.g. coffeescript), they use if expression as conditional expression.

    This patch adds if expression as the conditional expressionf for pocketlang. I think it is more clear than ternary operator especially there is more then one condition (if ... elif ... else ...).

    In the if expression, than can be omit, and end is not necessary (aslo not allowed). Example:

    print(if true then 123 else 456)
    print(if true 123 else 456)
    print(if false 123 elif false 546 else 789)
    
    a = if false
          123
        elif false
          456
        else
          789
    
    print(a)
    

    Output:

    123
    123
    789
    789
    
    opened by khchen 0
  • [Design] command like function call

    [Design] command like function call

    The Language Manual says:

    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.

    This patch extends it: parentheses for closure/method calling can be omitted if first argument is fn, name, string, number, primitive, map, list, etc.

    Example:

    a = 123
    sum = fn (a, b) return a + b end
    
    print 1, 2, 3
    print "a", "b", "c"
    print sum 10, 20
    print "x:", sum(10, 20), "y:", sum(30, 40)
    print [1, 2, 3]
    print {1: 1, 2: 2, 3: 3}
    print fn return 123 end (),
      fn return 456 end ()
    

    Output:

    1 2 3
    a b c
    30
    x: 30 y: 70
    [1, 2, 3]
    {2:2, 1:1, 3:3}
    123 456
    
    opened by khchen 0
  • [Enhancement] add iterator protocol for object

    [Enhancement] add iterator protocol for object

    Object can be used as iterator if _next and _value is defined. Similar to wren's iterator protocal. Example 1:

    class Countup
      def _init(first, last, step)
        self.first = first
        self.last = last
        self.step = step
      end
    
      def _next(iter)
        if iter == null then return self.first end
        iter += self.step
        if iter > self.last then iter = null end
        return iter
      end
    
      def _value(iter)
        return iter
      end
    end
    
    for i in Countup(0, 10, 2)
      print(i)
    end
    

    Output:

    0
    2
    4
    6
    8
    10
    

    Example 2:

    class Node
      def _init(val)
        self.val = val
        self.next = null
      end
    
      def _str()
        return "(${self.val})"
      end
    end
    
    class LinkedList
      def _init()
        self.head = null
      end
    
      def append(node)
        if self.head == null
          self.head = node
        else
          last = self.head
          while last.next do last = last.next end
          last.next = node
        end
      end
    
      def _next(iter)
        if iter == null then return self.head end
        return iter.next
      end
    
      def _value(iter)
        return iter
      end
    end
    
    ll = LinkedList()
    ll.append(Node(4))
    ll.append(Node(6))
    ll.append(Node(3))
    ll.append(Node(9))
    
    for n in ll
      print(n)
    end
    

    Output:

    (4)
    (6)
    (3)
    (9)
    

    Example 3:

    class StringIter
      def _init(text)
        self.text = text
      end
    
      def _next(iter)
        if iter == null then return 0 end
        iter += 1
        if iter >= self.text.length then iter = null end
        return iter
      end
    
      def _value(iter)
        return self.text[iter]
      end
    end
    
    for c in StringIter("hello")
      print(c)
    end
    

    Output:

    h
    e
    l
    l
    o
    
    opened by khchen 0
Owner
Thakee Nathees
yet another programmer.
Thakee Nathees
A small and fast programming language.

Pocketlang is a small (~3000 semicolons) and fast functional language written in C. It's syntactically similar to Ruby and it can be learned within 15

Thakee Nathees 1.4k Dec 28, 2022
PLP Project Programming Language | Programming for projects and computer science and research on computer and programming.

PLPv2b PLP Project Programming Language Programming Language for projects and computer science and research on computer and programming. What is PLP L

PLP Language 5 Aug 20, 2022
StarkScript - or the Stark programming language - is a compiled C-based programming language that aims to offer the same usability as that of JavaScript's and TypeScript's

StarkScript StarkScript - or the Stark programming language - is a compiled C-based programming language that aims to offer the same usability as that

EnderCommunity 5 May 10, 2022
ArkScript is a small, fast, functional and scripting language for C++ projects

ArkScript Documentation Discord server: invite link, to discuss the specification of the language and receive help Modules Nota bene: the project is r

ArkScript 484 Jan 1, 2023
A small, fast codeforces command line tool for competitive programming.

chainsaw: A Codeforces Commandline Tool chainsaw is a small and faster drop-in replacement for your copy and paste while attending Codeforces contests

Jiawei Wang 41 Dec 8, 2022
frost is a programming language with a focus on low-friction systems programming.

❄️ frost frost programming language About frost is a programming language with a focus on low-friction systems programming.

null 4 Nov 12, 2021
Pandex is a light but FAST programming language written in C . Pandex goal is that be hard & it's good for eductional goals

The Pandex programming language version 1.0.0.3 Pandex versions release type The Pandex version has four numbers. the first number holds 1 ( or 0 in s

null 8 May 23, 2022
cake is a programming language designed to be conventional as well as incredibly fast, natively available on these platforms.

cake The fast crossplatform programming language What's cake? cake is a programming language designed to be conventional as well as incredibly fast, n

Shadoww 4 Mar 6, 2022
Peregrine - A blazing fast language for the blazing fast world(WIP)

A Blazing-Fast Language for the Blazing-Fast world. The Peregrine Programming Language Peregrine is a Compiled, Systems Programming Language, currentl

Peregrine 1.5k Jan 2, 2023
C++11 header-only library that offers small vector, small flat map/set/multimap/multiset.

sfl library This is header-only C++11 library that offers several new containers: small_vector small_flat_set small_flat_map small_flat_multiset small

null 21 Dec 14, 2022
A collection of scripts written in many different programming languages and each developed independently to perform very specific tasks (big or small)

Script Collection A collection of scripts written in many different programming languages and each developed independently to perform very specific ta

Giovanni Rebouças 5 Aug 31, 2021
A fast and small port of Zstandard to WASM.

Zstandard WASM A fast and small port of Zstandard to WASM. (Decompress-only for now). Features Fast: Zstandard has been compiled with the -03 flag, so

Fabio Spampinato 13 Nov 9, 2022
dwm is an extremely fast, small, and dynamic window manager for X.

dwm - dynamic window manager dwm is an extremely fast, small, and dynamic window manager for X. My Patches This is in the order that I patched everyth

Christian Chiarulli 32 Dec 23, 2022
⛵ The missing small and fast image decoding library for humans (not for machines).

Squirrel Abstract Image Library The missing fast and easy-to-use image decoding library for humans (not for machines). Target Audience • Features • Im

Dmitry Baryshev 207 Dec 19, 2022
A family of small, fast, and simple bitmap fonts in single-file C headers

Blit A family of small, fast, and simple bitmap fonts in single-file C headers [go to repository] These are not intended as a replacement for fancy us

Andrew Reece 56 Dec 22, 2022
TinyGL: a Small, Free and Fast Subset of OpenGL

TinyGL A major overhaul of Fabrice Bellard's TinyGL to be more useful as a software rasterizer. Now with limited multithreading support Tightly tweake

Jim Huang 42 Dec 30, 2022
A small, fast, vectorizeable libm

jodiemath a small, fast, vectorizeable libm goals: all functions have absolute or relative error ~= 0.000010 or less, this isn't a fast math library,

null 8 Mar 29, 2022
C/C++ language server supporting multi-million line code base, powered by libclang. Emacs, Vim, VSCode, and others with language server protocol support. Cross references, completion, diagnostics, semantic highlighting and more

Archived cquery is no longer under development. clangd and ccls are both good replacements. cquery cquery is a highly-scalable, low-latency language s

Jacob Dufault 2.3k Jan 2, 2023
A perfect blend of C, Java, and Python tailored for those who desire a simple yet powerful programming language.

Fastcode A perfect blend of C, Java, and Python tailored for those who desire a simple yet powerful programming language. FastCode is a procedural/str

null 28 Aug 19, 2022