It's like Forth but in Python

Related tags

Miscellaneousporth
Overview

Porth

WARNING! This language is a work in progress!

It's like Forth but written in Python. But I don't actually know for sure since I never programmed in Forth, I only heard that it's some sort of stack-based programming language. Porth is also stack-based programming language. Which makes it just like Forth am I rite?

Porth is planned to be

  • Compiled
  • Native
  • Stack-based (just like Forth)
  • Turing-complete
  • Self-hosted (Python is used only as an initial bootstrap, once the language is mature enough we gonna rewrite it in itself)
  • Statically typed (the type checking is probably gonna be similar to the WASM validation)

(these are not the selling points, but rather milestones of the development)

Examples

Hello, World:

include "std.porth"

"Hello, World\n" stdout write

Simple program that prints numbers from 0 to 99 in an ascending order:

do dup print 1 + end ">
include "std.porth"

100 0 while 2dup > do
    dup print 1 +
end

Quick Start

Simulation

Simulation simply interprets the program.

$ cat program.porth
34 35 + print
$ ./porth.py sim program.porth
69

It is strongly recommended to use PyPy for the Simulation Mode since CPython is too slow for that. Try to simulate ./euler/problem04.porth using CPython and compare it with PyPy and Compilation Mode.

Compilation

Compilation generates assembly code, compiles it with nasm, and then links it with GNU ld. So make sure you have both available in your $PATH.

$ cat program.porth
34 35 + print
$ ./porth.py com program.porth
[INFO] Generating ./program.asm
[CMD] nasm -felf64 ./program.asm
[CMD] ld -o ./program ./program.o
$ ./program
69

Testing

Test cases are located in ./tests/ folder. The *.txt files contain inputs (command line arguments, stdin) and expected outputs (exit code, stdout, stderr) of the corresponding programs.

Run ./test.py script to execute the programs and assert their outputs:

$ ./test.py run

To updated expected outputs of the programs run the update subcommand:

$ ./test.py update

To update expected command line arguments and stdin of a specific program run the update input subcommand:

$ ./test.py update input ./tests/argv.porth new cmd args
[INFO] Provide the stdin for the test case. Press ^D when you are done...
Hello, World
^D
[INFO] Saving input to ./tests/argv.txt

The ./examples/ folder contains programs that are ment for showcasing the language rather then testing it, but we still can use them for testing just like the stuff in the ./tests/ folder:

$ ./test.py run ./examples/
$ ./test.py update input ./examples/name.porth
$ ./test.py update output ./examples/

For more info see ./test.py help

Usage

If you wanna use the Porth compiler separately from its codebase you only need two things:

By default the compiler searches files to include in ./ and ./std/. You can add more search paths via the -I flag before the subcommand: ./porth.py -I com ... . See ./porth.py help for more info.

Language Reference

This is what the language supports so far. Since the language is a work in progress everything in this section is the subject to change.

Data Types

Integer

Currently an integer is anything that is parsable by int function of Python. When the compiler encounters an integer it pushes it onto the data stack for processing by the relevant operations.

Example:

10 20 +

The code above pushes 10 and 20 onto the data stack and sums them up with + operation.

String

Currently a string is any sequence of bytes sandwiched between two ". No newlines inside of the strings are allowed. Escaping is done by unicode_escape codec of Python. No way to escape " themselves for now. No special support for Unicode is provided right now too.

When the compiler encounters a string:

  1. the size of the string in bytes is pushed onto the data stack,
  2. the bytes of the string are copied somewhere into the memory (the exact location is implementation specific),
  3. the pointer to the beginning of the string is pushed onto the data stack.

Those, a single string pushes two values onto the data stack: the size and the pointer.

Example:

include "std.porth"
"Hello, World" stdout write

The write macro from std.porth module expects three values on the data stack:

  1. the size of the buffer it needs to print,
  2. the pointer to the beginning of the buffer,
  3. and the output file descriptor where it needs to print to.

The size and the pointer are provided by the string "Hello, World". The file descriptor is stdout macro from std.porth.

Character

Currently a character is a single byte sandwiched between two '. Escaping is done by unicode_escape codec of Python. No way to escape ' themselves for now. No special support for Unicode is provided right now too.

When compiler encounters a character it pushes its value as an integer onto the stack.

Example:

'E' print

This program pushes integer 69 onto the stack (since the ASCII code of letter E is 69) and prints it with the print operation.

Built-in Words

Stack Manipulation

  • dup - duplicate an element on top of the stack.
a = pop()
push(a)
push(a)
  • swap - swap 2 elements on the top of the stack.
a = pop()
b = pop()
push(a)
push(b)
  • drop - drops the top element of the stack.
pop()
  • print - print the element on top of the stack in a free form to stdout and remove it from the stack.
a = pop()
print(a)
  • over
a = pop()
b = pop()
push(b)
push(a)
push(b)

Comparison

  • = - checks if two elements on top of the stack are equal. Removes the elements from the stack and pushes 1 if they are equal and 0 if they are not.
a = pop()
b = pop()
push(int(a == b))
  • != - checks if two elements on top of the stack are not equal.
a = pop()
b = pop()
push(int(a != b))
  • > - checks if the element below the top greater than the top.
b = pop()
a = pop()
push(int(a > b))
  • < - checks if the element below the top less than the top.
b = pop()
a = pop()
push(int(a < b))
  • >=
b = pop()
a = pop()
push(int(a >= b))
  • <=
b = pop()
a = pop()
push(int(a >= b))

Arithmetic

  • + - sums up two elements on the top of the stack.
a = pop()
b = pop()
push(a + b)
  • - - subtracts the top of the stack from the element below.
a = pop()
b = pop()
push(b - a)
  • * - multiples the top of the stack with the element below the top of the stack
a = pop()
b = pop()
push(b * a)
  • divmod
a = pop()
b = pop()
push(b // a)
push(b % a)

Bitwise

  • shr
a = pop()
b = pop()
push(b >> a)
  • shl
a = pop()
b = pop()
push(b << a)
  • bor
a = pop()
b = pop()
push(b | a)
  • band
a = pop()
b = pop()
push(b & a)

Control Flow

  • if else end - pops the element on top of the stack and if the element is not 0 executes the , otherwise .
  • while do end - keeps executing both and until produces 0 at the top of the stack. Checking the result of the removes it from the stack.

Memory

  • mem - pushes the address of the beginning of the memory where you can read and write onto the stack.
push(mem_addr)
  • . - store a given byte at the address on the stack.
byte = pop()
addr = pop()
store(addr, byte)
  • , - load a byte from the address on the stack.
addr = pop()
byte = load(addr)
push(byte)
  • .64 - store an 8-byte word at the address on the stack.
word = pop()
addr = pop()
store(addr, word)
  • ,64 - load an 8-byte word from the address on the stack.
word = pop()
byte = load(word)
push(byte)

System

  • syscall - perform a syscall with n arguments where n is in range [0..6]. (syscall1, syscall2, etc)
syscall_number = pop()

   
    
for i in range(n):
    arg = pop()
    
    

     

     
    
   

Macros

Define a new word write that expands into a sequence of tokens 1 1 syscall3 during the compilation.

macro write
    1 1 syscall3
end

Include

Include tokens of file file.porth

include "file.porth"
Owner
Tsoding
Recreational Programming
Tsoding
NExT-Ford-aula4 - NExT Ford aula4

Questão 1: vocês deveram fazer o passo a passo de como ficará as pilhas(Stack) e

Gerson 1 Jan 06, 2022
Clock in automatically in SCU.

auto_clock_in Clock in automatically in SCU. Features send logs to Telegram bot How to use? pip install -r requirements.txt () edit user_list, token_A

2 Dec 13, 2021
Aggressor script that gets the latest commands from CobaltStrikes web site and creates an aggressor script based on tool options.

opsec-aggressor Aggressor script that gets the latest commands from CobaltStrikes opsec page and creates an aggressor script based on tool options. Gr

JP 10 Nov 26, 2022
little proyect to organize myself, but maybe can help someone else

TaskXT 0.1 Little proyect to organize myself, but maybe can help someone else Idea The main idea is to ogranize you work and stuff to do, but with onl

Gabriel Carmona 4 Oct 03, 2021
Black-Scholes library implemented as a Cairo smart contract

Cairo Black-Scholes Library Black-Scholes library implemented as a Cairo smart contract. All inputs, outputs, and internal calculations use 27-digit f

Aditya Raghavan 47 Dec 19, 2022
This is a survey of python's async concurrency features by example.

Survey of Python's Async Features This is a survey of python's async concurrency features by example. The purpose of this survey is to demonstrate tha

Tyler Lovely 4 Feb 10, 2022
Inviare messaggi tramite app IO a partire da dati contenuti in file .csv

parlaConIO Inviare messaggi tramite app IO a partire da dati contenuti in file .csv -- Nessun obbligo, ma in caso di clonazione o uso del programma c

Francesco Del Castillo 6 Aug 22, 2022
An OrpheusDL Tidal module

OrpheusDL - Tidal A Tidal module for the OrpheusDL modular archival music program Report Bug · Request Feature Table of content About OrpheusDL - Tida

Daniel 54 Dec 29, 2022
2 Way Sync Between Notion Database and Google Calendar

Notion-and-Google-Calendar-2-Way-Sync 2 Way Sync Between a Notion Database and Google Calendar WARNING: This repo will be undergoing a good bit of cha

248 Dec 26, 2022
Chat meetup

FLiP-Meetup-Chat Chat meetup create function bin/pulsar-admin functions create --auto-ack true --jar pulsardjlexample-1.0.jar --classname "dev.pulsarf

Timothy Spann 1 Dec 09, 2021
This application demonstrates IoTVAS device discovery and security assessment API integration with the Rapid7 InsightVM.

Introduction This repository hosts a sample application that demonstrates integrating Firmalyzer's IoTVAS API with the Rapid7 InsightVM platform. This

Firmalyzer BV 4 Nov 09, 2022
A Python application that helps users determine their calorie intake, and automatically generates customized weekly meal and workout plans based on metrics computed using their physical parameters

A Python application that helps users determine their calorie intake, and automatically generates customized weekly meal and workout plans based on metrics computed using their physical parameters

Anam Iqbal 1 Jan 13, 2022
Laurence Billingham 1 Feb 16, 2022
A Kodi add-on for watching content hosted on PeerTube.

A Kodi add-on for watching content hosted on PeerTube. This add-on is under development so only basic features work, and you're welcome to improve it.

1 Dec 18, 2021
🔩 Like builtins, but boltons. 250+ constructs, recipes, and snippets which extend (and rely on nothing but) the Python standard library. Nothing like Michael Bolton.

Boltons boltons should be builtins. Boltons is a set of over 230 BSD-licensed, pure-Python utilities in the same spirit as — and yet conspicuously mis

Mahmoud Hashemi 6k Jan 06, 2023
HiSim - House Infrastructure Simulator

HiSim is a Python package for simulation and analysis of household scenarios using modern components as alternative to fossil fuel based ones.

FZJ-IEK3 17 Dec 17, 2022
Implementation of the MDMC method to search for magnetic ground state using VASP

Implementation of MDMC method ( by Olga Vekilova ) to search for magnetic ground state using VASP

Utkarsh Singh 1 Nov 27, 2021
A collection of convenient parsers for Advent of Code problems.

Advent of Code Parsers A collection of convenient Python parsers for Advent of Code problems. Installation pip install aocp Quickstart You can import

Miguel Blanco Marcos 3 Dec 13, 2021
Contains the code of my learning of Python OOP.

OOP Python This repository contains the code of my learning of Python OOP. All the code: is following PEP 8 ✅ has proper concept illustrations and com

Samyak Jain 2 Jan 15, 2022
Viewer for NFO files

NFO Viewer NFO Viewer is a simple viewer for NFO files, which are "ASCII" art in the CP437 codepage. The advantages of using NFO Viewer instead of a t

Osmo Salomaa 114 Dec 29, 2022