Sea (a compiled language)
fuzzyastrocat (831)

Hello everyone! This is my first post, so if it's boring I apologize :D

Just wanted to share a little compiled language I made called Sea. It's called Sea because, well, Sea shares many things in common with C. I chose C to mimic because this was my first compiled language — given that C is so low-level, I figured I wouldn't have to do too much work translating to x86.

A quick overview of the language

In case any of you want to try it out, here's a quick overview of the syntax/semantics.

To start, we'll take the simple "hello, world" program:

    import "stdlib.sea";
    int function main {
            println("Hello, world!");
            0;
    }

Here we immediately see a few differences between C and Sea:

  • Import is not a preprocessor routine, it's a keyword
  • Functions are defined as <type> function <name>
  • Functions automatically return their last expression — to suppress this, the last expression can be void;
  • Arguments in functions are declared differently — instead of putting arguments between parentheses, they are written as null declarations on the following line:
    int function my_function
            int my_arg_1;
            int my_arg_2;
    {
            // some code
     }

Control flow (if, else, while) is implemented as a "postfix operator":

    1 == 2
            :then {
                    println("Whoa, math broke"); // And no, this won't get printed :D
            }

A for-loop can be emulated with a block scope and a while:

    {int i = 0; i < 5
            :while {
                    printf("%d", i);
                    i++;
            }}

These control flow constructs can be extended — an excerpt taken from the stdlib:

    int::isZero {
        $int
            :else {
                $();
            }
    }

$int represents the int in question, and $() represents execution of the block given to the control statement. We could "call" this like so:

    0
         :isZero {
                 println("Hey math works again!");
         }

Sea has support for ints, chars, pointers, strings (char*), and moderate support for floats. If you want to see more about the language, peruse stdlib.sea and the tests (and oldtests, though some of those are outdated) folders in the repl.

EDIT: stdlib.sea uses what might be a confusing doc notation, so let me explain that here.

Comments

Sea comments behave just like C comments:

    // This
    /* will
        not
        be
    */ // Evaluated

However, there is a doc notation (used by SeaLib to generate simple HTML docs for a file). It is the following:

    [[[header]]]
    The header must be the first line of the file (outside of line or block comments).  It gives  a description of the file to follow. // This line is the file info

    [[your_function]] // Descriptor doc — gives info about a function
    A cool function I just wrote for demo purposes

    void function your_function {
            println("Hello, world!");
    }

    // Add more functions with their descriptor docs

SeaLib translates that to the following:

And yes, that file would actually run (aside from saying "entry point main is not defined"). Doc headers are ignored (along with the line after) just like normal comments.

Future

"That's neat — but why are you posting it here right now?"

Unfortunately, I'm going to abandon Sea (in favor of a newer language, Curta). Why? Two things:

  • As the language became more complex, I noticed a few things I had done not-quite-nicely in the compiler were becoming difficult to manage. I was faced with either using bad tools or buying (re-coding) new tools.
  • I was actually wrong about translating from a C-like language to x86 being easy. While the actual conversions themselves are not difficult, finding the proper x86 commands can be very difficult! For instance, there is no power function for the SSE floating point system — and all the tools I needed to make a power function were either nonexistent or difficult to implement.

So Sea will probably remain in its current state [for the rest of time].

In the aforementioned newer language (Curta), I am learning from my mistakes — it will compile to C++, with the added benefit that it will work on some embedded systems (most notably the Arduino). Stay tuned!

EDIT: Curta is now here: https://repl.it/talk/challenge/Curta-Lets-make-hard-things-easy/51820

You are viewing a single comment. View All
EpicGamer007 (620)

Amazing job! Just a question, why and how did you use js? I thought most programming languages were made in c and c++...

fuzzyastrocat (831)

@AbhayBhat Glad you asked! Many interpreted languages are made in C and C++. Why? Because C and C++ are fast, and interpreted languages need to be built on a fast language since they are inherently slow. However, a compiled language is inherently fast, because it's actually not running on JS — it's running on x86. The job of the JS is to convert the Sea programs to x86 assembly, and x86 is very very fast.
So, to answer your question: I used JS because JS is easy to code in, so I wouldn't be hindered by it (and performance of the host language doesn't really matter much for compiled languages).

As a side note: after completing a compiled language, one usually rewrites the language source in the language itself. This is so that you get rid of the JS.

fuzzyastrocat (831)

Note: Re-reading my post, it might be a little unclear. Here's the basic idea:

If my language was interpreted, then the JS would be the one running the language. JS is slow, so I don't want a slow thing running my language since my language will run even slower.
Since the language is compiled, JS doesn't actually run the language. Instead, JS just translates it into machine code, which is super fast. Even though JS is slow, the JS doesn't actually do a whole lot — so it's acceptable to use it.

EpicGamer007 (620)

@fuzzyastrocat, Absolutely Amazing! I wish there was something like this in java..

AmazingMech2418 (909)

@AbhayBhat I'm pretty sure you can do this in Java too! As long as you know Assembly or at least another compiler language like C, you can just use file I/O and then call a compiler or assembler using Runtime.getRuntime().exec(yourCodeHere).

AmazingMech2418 (909)

@AbhayBhat I just wish I knew Assembly so I could make something like this. LOL!

AmazingMech2418 (909)

@AbhayBhat But, it is actually possible even to compile to Java and then use a Java compiler to create a language!

fuzzyastrocat (831)

@AbhayBhat, you can do this in Java if you want also — there's nothing special about JS for compilers. What @AmazingMech2418 said above is also perfectly valid — you could use Java to compile (translate) your language to Java!

AmazingMech2418 (909)

@fuzzyastrocat Runtime.getRuntime().exec just runs a Bash script. Basically, you can use that to call the compiler or assembler depending on how you're making the compiler (either directly to Assembly or transpiling to another language which is then compiled). It's like the child_process.exec function in JS.

fuzzyastrocat (831)

@AmazingMech2418 Ah ok, yes that would run the assembler (or the compiler of the non-assembly language if applicable — though I think that might be considered an assembler also in that case?). But the compiler is the program itself — so unless the program exec's itself (creating an infinite loop) you probably wouldn't use that to run the compiler.

AmazingMech2418 (909)

@fuzzyastrocat I mean like if you are just transpiling to C to make it easier and using clang or gcc with exec. However, if just compiling to Assembly, you are correct and you would only need to run the assembler.

fuzzyastrocat (831)

@AmazingMech2418 Right ok, I thought by "compiler" you meant the compiler of the custom language :D