A fun and simple language with NO classes whatsoever!

Overview

Europa Lang Discord Server

Europa Lang

This language aims to be simple, minimal, and compact. There will not be any classes whatsoever, and importing other files should be painless.

Example

use Math;
use Io;

Io.println("Hello, World!");
var input = Io.stdin.readline();
Io.println("You said: " + input);

Io.println("Random Number 0..1: " + Math.random());

var struct = {{
    a_sruct = 'strings can look like this too'
}};

Io.println(struct.a_struct);

fn add_two(a, b) {
    return a + b;
}

var a = true;
var b = true;

while true {
    if a == b {
        break;
    } elif a != b {
        continue;
    } else {
        break;
    }
}

var array = [1, 2, 3];
for i in array {
    Io.println(i);
}

Credits

  • @justamirror and Dart for name and language design suggestions.
  • @CoolCoderSJ for creating the discord server, along with language design suggestions!
  • @SixBeeps for designing the Europa logo!
Comments
  • Added random (not sure why Europa is complaining tho)

    Added random (not sure why Europa is complaining tho)

    This adds random into the Europa math stdlib feature. It should have the following syntax:

    var someRandomValue = random(minimum, maximum);
    

    Not sure why it throws this error tho:

    Screen Shot 2021-09-08 at 4 34 40 PM

    Can some of the main devs help me?

    opened by darkdarcool 7
  • Implementing References

    Implementing References

    As arrays and maps become increasingly hard to implement due to a big problem: references.

    Take this example:

    var a = {{ array: [1, 2, 3] }};
    a."array"[1] = 3;
    

    (figure 1)

    at the moment with what we have, implementing this will be pretty much impossible, albeit I haven't implemented it yet.

    Also take this planned example:

    var a = 5, b = 6;
    
    fn swap(ref a, ref b) {
      var t_a = cpy a, t_b = cpy b;
    
      a = t_b;
      b = t_a;
    }
    

    (figure 2)

    Proposed solutions

    References is a 'type', and it is:

    Ref(Token)
    

    where Token is the variable where the original data is stored.

    **Pros: ** figure 2 **Cons: ** figure 1

    References are in a new HashMap called the 'heap'. They include values that can get mutated.

    **Pros: ** Solves both figures 1 and 2 if implemented correctly. **Cons: ** Very very hard to implement correctly

    We make a mutable reference of the environment and just mutate them around **Pros: ** Solves both figures 1 and 2 if implemented correctly. **Cons: ** The ref type still might be needed

    opened by cursorweb 5
  • Tips

    Tips

    I added a version command if that's helpful :)

    Also just some things I noticed


    For your lexer, instead of getting all the tokens at once, you could also get them when you need them, like this:

    fn parser() {
        tok = lexer.eat(); // get next token
        if tok.type == TokType::IF {
            // get next token; if next token is not an open bracket, throw error
            tok = lexer.eat(TokType::OPEN_BRACKET, "expected open bracket after 'if' keyword");
        }
    }
    

    It doesn't really matter which way you do it. I kinda like the second way thought since you have more control over the lexing process, and it's much easier to deal with syntax errors.


    For your parser, you have a lot of duplicate code with your functions: comp, add, mult, unary. I would just suggest having unary and binary.

    Same thing with types.rs, there's a bunch of duplicate code. I'm not sure how it works in Rust, but you could try to have a generic binary expression function, and just pass in a lambda like this:

    pub fn evaluate_binary_expression(
        &self,
        other: &Type,
        operation:   &dyn Fn(i32, i32) -> TResult,        // lambda function
        div_by_zero: bool,                                // if false, and division by 0 is encountered, throw error
        op_name:     &str                                 // name of the operator to display in the error message
    ) -> TResult {
    
            if let (Self::Float(a), Self::Float(b)) = (self, other) {
                if !div_by_zero && *b == 0f32 {
                    return Err("Division by 0.".into());
                }
    
                return Ok(Self::Float(operation(a, b)));
            }
    
            // not sure how str concat work in rust :/
            Err("Operator '" + op + "' can only be applied to numbers.".into())
    }
    

    Hope it helps :D

    opened by DynamicSquid 3
  • Expanded math stdlib

    Expanded math stdlib

    Unlike darkdarcool's random function, added a randrange function that actually works. Also added cos and tan. Also also, added dirty parse function impl to Types so it's shorter and more consice to convert to primitives.

    opened by AntimatterReactor 2
  • Made Lexer Easier to Edit

    Made Lexer Easier to Edit

    Not too big of an issue, but editing tokens in the lexer was a complicated task. Added hashmaps for different types of tokens, such as operators or separators, as well as a group for braces and double braces.

    opened by seanlnge 1
  • String escapes

    String escapes

    Allows C-style escapes in strings.

    • \n: newline/line feed (LF)
    • \r: return (CR)
    • \t: (horizontal) tab (HT)
    • \a: alert (BEL)
    • \b: backspace (BS)
    • \e: escape (ESC)
    • \f: form feed (FF)
    • \v: vertical tab (VT)
    • \\: backslash/reverse solidus
    • \': single quote/apostrophe
    • \": double quote/quotation mark
    • \?: question mark
    • \o___: octal byte
    • \x__: hexadecimal byte
    • \u____: four-nibble (2B) hexadecimal
    • \U________: eight-nibble (4B) hexadecimal

    Throws SyntaxError with "Invalid string escape." on error.

    opened by 19wintersp 1
  • Implement optional args

    Implement optional args

    Finally, the feature we all want!

    use io.println;
    
    fn add(a, b, print = false) {
      if print { println(a + b); }
      return a + b;
    }
    
    println(add(1, 2)); // 3
    add(1, 2, print = true); // 3
    
    opened by cursorweb 0
  • Add features to REPL

    Add features to REPL

    Add enhanced line editing, multi-line editing, bracket pair checking, history, history file ("~/.europa_history" on Unix, "%USERPROFILE%/.europa_history" on Windows), evaluated expression returning in REPL, and allows missing semicolon before EOF.

    Also adds as dependency Rustyline 9.1 (101kB) for these features.

    Allows future expansion with hints, completion and syntax highlighting.

    Addresses #25 and some of #26.

    opened by 19wintersp 0
  • STDLIB features

    STDLIB features

    STDLIB features that need to be added

    • [ ] io
      • [x] println
      • [x] print
      • [x] flush
      • [x] readln
      • [ ] read (no new line)
      • [ ] passread (get input like read but no output when the user types it, produces no new line, but can if you wanna)
    • [ ] Date
      • [ ] now
      • [ ] epoch
      • [ ] get_minute
      • [ ] get_second
      • [ ] get_day
      • [ ] get_month
      • [ ] get_year
    • [ ] Path module like JS
      • [ ] join
    • [ ] fs
      • [ ] read_file
      • [ ] write_file
      • [ ] file_exists
    • [ ] http
      • [ ] get
      • [ ] post
      • [ ] put
      • [ ] all
    opened by darkdarcool 5
  • DynamicSquid's Suggestions

    DynamicSquid's Suggestions

    Thanks to @DynamicSquid's pr #2, we have some things to optimize! Here they are, verbatim:

    I added a version command if that's helpful :)

    Also just some things I noticed

    For your lexer, instead of getting all the tokens at once, you could also get them when you need them, like this:

    fn parser() {
        tok = lexer.eat(); // get next token
        if tok.type == TokType::IF {
            // get next token; if next token is not an open bracket, throw error
            tok = lexer.eat(TokType::OPEN_BRACKET, "expected open bracket after 'if' keyword");
        }
    }
    

    It doesn't really matter which way you do it. I kinda like the second way of thought since you have more control over the lexing process, and it's much easier to deal with syntax errors.

    For your parser, you have a lot of duplicate code with your functions: comp, add, mult, unary. I would just suggest having unary and binary.

    Same thing with types.rs, there's a bunch of duplicate code. I'm not sure how it works in Rust, but you could try to have a generic binary expression function, and just pass in a lambda like this:

    pub fn evaluate_binary_expression(
        &self,
        other: &Type,
        operation:   &dyn Fn(i32, i32) -> TResult,        // lambda function
        div_by_zero: bool,                                // if false, and division by 0 is encountered, throw error
        op_name:     &str                                 // name of the operator to display in the error message
    ) -> TResult {
    
            if let (Self::Float(a), Self::Float(b)) = (self, other) {
                if !div_by_zero && *b == 0f32 {
                    return Err("Division by 0.".into());
                }
    
                return Ok(Self::Float(operation(a, b)));
            }
    
            // not sure how str concat work in rust :/
            Err("Operator '" + op + "' can only be applied to numbers.".into())
    }
    

    Hope it helps :D

    opened by cursorweb 9
Owner
Europa Lang
Europa Lang's official GitHub Org!
Europa Lang
Repository for the Rust Language Server (aka RLS)

Rust Language Server (RLS) The RLS provides a server that runs in the background, providing IDEs, editors, and other tools with information about Rust

The Rust Programming Language 3.6k Jan 7, 2023
A language-agnostic "shebang interpreter" that enables you to write scripts in compiled languages.

Scriptisto It is tool to enable writing one file scripts in languages that require compilation, dependencies fetching or preprocessing. It works as a

Igor Petruk 238 Dec 30, 2022
The Curly programming language (now in Rust!)

Curly Curly is a functional programming language that focuses on iterators. Some of its main implementation features include sum types, iterators, lis

Curly Language 30 Jan 6, 2023
Super lightweight and dead-simple CI detection.

This crate tells you if you're in a CI environment or not. It does not tell you which you're in, but it makes a good effort to make sure to accurately

Kat Marchán 9 Sep 27, 2022
🎭 A CLI task runner defined by a simple markdown file

mask is a CLI task runner which is defined by a simple markdown file. It searches for a maskfile.md in the current directory which it then parses for

Jake Deichert 756 Dec 30, 2022
A simple utility for multithreading a/synchronization

Flowync Quick Example use flowync::Flower; fn main() { let flower = Flower::<i32, String>::new(1); std::thread::spawn({ let handle =

Adia Robbie 12 Dec 5, 2022
Detects usage of unsafe Rust in a Rust crate and its dependencies.

cargo-geiger ☢️ A program that lists statistics related to the usage of unsafe Rust code in a Rust crate and all its dependencies. This cargo plugin w

Rust Secure Code Working Group 1.1k Dec 26, 2022
The Git Commit Message and Changelog Generation Framework :book:

git-journal ?? The Git Commit Message and Changelog Generation Framework Table of contents: TL;DR Installation Usage Default output Template output Co

Sascha Grunert 551 Jan 4, 2023
⚙️ Workshop Publishing Utility for Garry's Mod, written in Rust & Svelte and powered by Tauri

⚙️ gmpublisher Currently in Beta development. A powerful and feature-packed Workshop publisher for Garry's Mod is finally here! Click for downloads Ar

William 484 Jan 7, 2023
Create evolving artistic images with hot-code-reloaded Lisp and GLSL.

Shadergarden is a tool for building hot-code-reloadable shader pipelines. For a tutorial for how to get started, consult the introductory

Tonari, Inc 101 Dec 29, 2022
A neofetch alike program that shows hardware and distro information written in rust.

nyafetch A neofetch alike program that shows hardware and distro information written in rust. installing install $ make install # by default, install

null 16 Dec 15, 2022
Simple GTK Rust Fuzzer which aims to test all available classes and functions in GTK.

Gtk Rust Fuzzer Simple GTK Rust Fuzzer which aims to test all available classes and functions in GTK. It finds bugs inside GTK functions, GTK exported

Rafał Mikrut 8 Nov 19, 2022
Catch Tailwindcss Errors at Compile-Time Before They Catch You, without making any change to your code! Supports overriding, extending, custom classes, custom modifiers, Plugins and many more 🚀🔥🦀

twust Twust is a powerful static checker in rust for TailwindCSS class names at compile-time. Table of Contents Overview Installation Usage Statement

null 15 Nov 8, 2023
cargo extension that can generate BitBake recipes utilizing the classes from meta-rust

cargo-bitbake cargo bitbake is a Cargo subcommand that generates a BitBake recipe that uses meta-rust to build a Cargo based project for Yocto Install

null 60 Oct 28, 2022
Mewl, program in cats' language; A just-for-fun language

Mewl The programming language of cats' with the taste of lisp ?? What,Why? Well, 2 years ago in 2020, I created a esoteric programming language called

Palash Bauri 14 Oct 23, 2022
Simple Programming Language for fun.

Chap Chap is an Easy to learn, dynamic, interpretive, isolated, and keywordless scripting language written in Rust. It is useful when you want your us

Ali Ghahremani 36 Oct 6, 2023
Programming language just for fun, will kill LUA some day.

Loom Programming language just for fun, will kill LUA some day. Currently development of this language is algorithm driven. I'm trying to implement va

Mateusz Russak 5 Dec 4, 2023
A simple and fun way to view the time!

Concentric Time A simple and fun way to view the time! Screenshots Dark mode Light mode Dev This project uses Dioxus (a Rust-Wasm framework) and does

Parker McMullin 9 Oct 23, 2022
☢ Guerrilla (or Monkey) Patching in Rust for (unsafe) fun and profit.

Guerrilla Guerrilla (or Monkey) Patching in Rust for (unsafe) fun and profit. Provides aribtrary monkey patching in Rust. Please do not use this crate

Ryan Leckey 97 Dec 16, 2022
Breaking your Rust code for fun and profit

Breaking your Rust code for fun & profit this is an architecture-preview, not all components are there This is a mutation testing framework for Rust c

null 533 Dec 18, 2022