Giter Club home page Giter Club logo

edina's Introduction

Logo

edina πŸ“š

Edina is a simple multi-paradigm programming language. It currently features a JVM compiler, a REPL and an ever expanding standard library.

Edina is mostly a hobby project. Due to its stack-oriented design it's a little restrictive and hard to program in, but that's what makes it fun in my opinion.

Paradigms: imperative , concatenative , stack-oriented

"Hello World" program

Source code -> Java bytecode Java bytecode

Contents

  1. Try it out
  2. Specification
  3. Running the JVM compiler
  4. Building
  5. Included scripts
  6. EdinaJ development
  7. Credit

Try it out

To try out Edina follow these steps:

  1. Clone the repository
  2. Build the project (see Building)
  3. Create script.edina
  4. Copy the contents of examples/hello_world.edina into script.edina
  5. Compile the script (java -jar edinaj/target/edinaj.jar -P my.script -F script.edina -O script.jar)
  6. Run the compiled Jar (java -jar script.jar)

You can also invite the Edina Discord bot to your server and try it there without performing any of these manual steps.

Specification

Edina programs are usually called scripts, even though they are compiled. A script contains many commands. Edina is not whitespace sensitive, and you do not have to terminate your statements. The only place where a terminator command is needed is in routine-, loop- and if-blocks.

Let's start with the most important feature first: Comments! Edina comments are started with a # and span across the rest of the line.

Comments are very important for the readability of code - the stack-oriented design can make it difficult to understand what code is doing with a quick glance. Documenting your Edina code helps others understand what is going on. This is usually done with so-called stack diagrams.

A stack diagram in Edina describes how the stack will look like after a set of operations has finished. Stack diagrams usually look like this [a, b, c] where the leftmost item represents the top and the rightmost item represents the bottom of the stack.

# This is a comment
1 2 3 pop swap  # This is another comment

# How stack diagrams are used:
rt multi_dup
  # [N, X]
  # X = Item to duplicate
  # N = How many times to duplicate X
  
  while
    # [N, X]
    swap dup   # [X, X, N]
    1 3 rroll  # [N, X, X]
    1 swap -   # [N-1, X, X]
  end
  # [N(0), X, ...]
  pop  # [X, ...]
end

Edina features a small set of commands which, when combined, can be used to create powerful and complex programs.

# General commands
pop         # Drop the topmost element from the stack     [a] -> []
dup         # Duplicate the topmost item of the stack     [a] -> [a, a]
swap        # Swap the two topmost items of the stack     [a, b] -> [b, a]
over        # Duplicate the 2nd topmost item to the top   [a, b] -> [b, a, b]
lroll       # Roll X items N times to the left            [X(3), N(1), a, b, c] -> [b, c, a]
rroll       # Roll X items N times to the right           [X(3), N(1), a, b, c] -> [c, a, b]
end         # End the code block / Only used in routines, ifs and loops

# Comparison commands
# Peeks two values and pushes result (either 1 or 0 (true or false))
eq         # True if topmost two items are equal          [a, b] -> [a==b, a, b]
neq        # True if topmost two items are not equal      [a, b] -> [a!=b, a, b]
gt         # True if topmost item > 2nd topmost item      [a, b] -> [a>b, a, b]
gte        # True if topmost item >= 2nd topmost item     [a, b] -> [a>=b, a, b]
lt         # True if topmost item < 2nd topmost item      [a, b] -> [a<b, a, b]
lte        # True if topmost item <= 2nd topmost item     [a, b] -> [a<=b, a, b]

# Arithmetic / bitwise commands
# Remember: Top of the stack in stack diagrams is left
+           # Pop top two items and push sum              [a, b] -> [a+b]
-           # Pop top two items and push difference       [a, b] -> [a-b]
*           # Pop top two items and push product          [a, b] -> [a*b]
/           # Pop top two items and push quotient         [a, b] -> [a/b]
&           # Pop top two items and push ANDed result     [a, b] -> [a&b] 
|           # Pop top two items and push ORed result      [a, b] -> [a|b] 
^           # Pop top two items and push XORed result     [a, b] -> [a^b] 
~           # Pop top item and push flipped result        [a] -> [~a]


3 5 -   # 5 - 3
1 8 +   # 8 + 1
4 3 ^   # 3 ^ 4

In addition to these commands, any signed integer (limited to 64 bits) and string (enclosed by two quotation marks) will act as a push command and will be pushed to the stack.

123         # [] -> [123]
-123        # [] -> [-123]
"abc"       # Len + chars as bytes / [] -> [3, 99, 98, 97]
            # Strings are naturally reversed due to the stack

Edina also supports routines (aka functions, methods, sub-routines, ...), ifs, loops and importing other scripts.

# ------ Imports ------
# Import statements have to be placed at the beginning of the script
import "stdlib/io/std"
# You can assign custom names to imported scripts
import "stdlib/math/ints" as custom_import_name
# You can call the declared global routines of the imported scripts
"Hi" :std.println_out               # -> import "stdlib/io/std"
123 :custom_import_name.int_to_str  # -> import "stdlib/math/ints" as custom_import_name

# ------ Routines ------
# Declaring a routine called my_routine
# Routines whose name starts with an underscore are internal and can not be called by
# other scripts
rt my_routine
  # Insert routine code here
end
.my_routine  # Calling my_routine

# ------ If ------
# if will pop the top stack value and check if it is greater than zero
if
  # Code
else if
  # Else if code
else
  # Else code
end

# ------ Loops ------
# while (peek_top_stack_item() != 0)
while
  # Code
end
# while (peek_top_stack_item() == 0)
until
  # Code
end

In order to interact with the host system, Edina features a few so-called "native calls". These native calls are heavily inspired by Linux syscalls.

native_stack_debug      # Print the stack contents to stdout    [] -> []
native_open             # Open a file                           [FLAGS, PATH] -> [FD]
native_write            # Write data to file descriptor         [FD, DATA] -> [RES]
native_read             # Read data from file descriptor        [FD, AMT] -> [RES]
native_close            # Close an opened file descriptor       [FD] -> [RES]
native_time             # Get current time in seconds           [] -> [TIME]

Running the JVM compiler

Please refer to the EdinaJ README to see the possible command line arguments.

EdinaJ requires at least Java 17. The generated Jars require at least Java 8.

Building

To build Edina you will need Java 17, Git and Maven.

  1. git clone https://github.com/cerus/edina.git
  2. cd edina
  3. mvn clean package or ./scripts/full_build.sh

Final EdinaJ Jar: edinaj/target/edinaj.jar
Final CLI / REPL Jar: cli/target/edina-cli.jar
Final EdDoc Jar: eddoc/target/eddoc.jar

Included scripts

This repository contains a few scripts in the scripts/ directory that make Edina development easier.

generate_asm.sh: Generate OW2 ASM for the EdinaJ Stack, Natives and Launcher classes
cleanup.sh: Delete any asm_*.txt files (generated by generate_asm.sh)
asm_to_code.sh: Integrate generated ASM files into the respective compiler steps
full_build.sh: generate_asm.sh && asm_to_code.sh && cleanup.sh

EdinaJ development

Developing the JVM compiler is pretty straight forward. The asm package contains "templates" for the Launcher, Stack and Natives classes. These templates can be converted to OW2 ASM code and inserted into their respective compiler steps.

Most of the compilation process is split up into CompilerSteps. This is an attempt to keep the code clean and organized. Each command has their own compiler step for example.

See the compiler step package or Compiler class for more details.

Credit

Inspired by Forth & Porth by Daily Tsoding

Logo was generated by DALLΒ·E mini / craiyon.com

'hello_world.edina' banner was created with carbon.now.sh

Dedicated to Edina Of Coboldcastle (*2008-†2020)

edina's People

Contributors

cerus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

edina's Issues

Odd choice for ifs

Hi, just a note really: I found having different flavours for if test conditions a bit of an odd choice, instead of offering eq, lt, lte, gt, gte binary functions that respond with true, false and then having a single if, which would lead to leaner code. This is also a bit of a contradictory decision to the way while works. while checks by default for a nonzero condition. Which means that "while a number is positive" has to involve an if. With a gt, lt, gte, ... all you have to do is workout an expression and then let if, while "branch" depending on the result of that expression.

Multiplication symbol typo

Issue description

Typo in README.md

To reproduce

Navigate to the project's github repository and read section "Specification"

Expected behaviour

* # Pop top two items and push product

Screenshots / videos

image

Component

Docs

If you chose 'other': Specify the component

No response

Additional information

...sorry to be the typo person. Cool project anyway.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.