Giter Club home page Giter Club logo

enact's People

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

somerandomdev49

enact's Issues

Modify lexer for new syntax

The language has changed significantly, see #73. Accordingly, the lexer will need to be updated. Curly braces are now the block delimiters as opposed to : and end. Semicolons have been added back in, keywords have been added and changed, and string interpolation is now supported. Bitwise operators have been added.

Improve const semantics

Currently, when defining a variable with const, all that is ensured is that the variable itself is not reassigned. Properties of the variable can still be reassigned and changed - I'd like this not to be the case.

Here's an example of what I'm talking about:

const arr = [1, 2, 3, 4, 5]

// You can't do this:
arr = [1, 2]

// But you can do this:
arr[0] = 2
// This shouldn't be allowed!

// Same applies for structs:
struct Person:
    name string
    age int
end

const jim = Person("Jim", 29)

// You can't do this:
jim = Person("Sam", 45)

// But you can do this:
jim.name = "Sam"
// And you shouldn't be able to!

Implement tuples

Tuples need to be implemented at some stage. Here's what the syntax is looking like:

// Tuple expression
(2, "yee")

const tuple = ("Jim", 99, 131.5)

// Deconstruction
var (name, age, height) = tuple

// Indexing
tuple.0 == name

// Selective deconstruction
var (name2, _, _) = tuple

// Given deconstruction
given tuple:
    when ("Jim", _, 21.01):
        print("Jim is short")
    when (name, age, height):
        print(name+" is "+string(age)+" years old and "+string(height)+"cm high")
end

Preserve environment in REPL

This is a lower-priority issue at the moment, but the REPL should be preserving the environment as it goes, e.g:

enact > const foo = 2
enact > foo (you get an "undefined" error, but you shouldn't!)

Due to the way everything works right now this isn't as simple to implement as it may seem - the bytecode chunk must be preserved and execution must be paused rather than stopped.

Implement generics

Not implementing generics initially was a mistake- each loops depend on their implementation.

Fix Travis CI

Fix the issues with Travis CI introduced in #36.
The version of Clang preinstalled is too old and for some reason I am unable to install a newer version.

Change `else` in syntax to `otherwise`, or make both work.

Because this language is intended to be simple, I think otherwise keyword would be better than else. Also, for experienced programmers, else would be better, so it will be nice to have both else and otherwise.

so, in the example from README:

// FizzBuzz in Enact
each i in 1..20:
    given (i % 3 == 0, i % 5 == 0):
        when (true, true):
            print("FizzBuzz")
        when (true, false):
            print("Fizz")
        when (false, true):
            print("Buzz")
        otherwise:   // <-- this looks better for beginners.
            print(i)
    end
end

Implement a compiler and VM

Now that parsing and analysis are down, it's time to write a compiler and VM.
To achieve this, I'll need to design a bytecode instruction set, write a VM to run it, and then write a compiler to convert the AST to bytecode.

The following classes need to be implemented:

  • Value representation: Value, Object
  • Bytecode: Chunk
  • VM: VM
  • Compiler: Compiler

Implement references

I'd now like to implement references, as in the following:

const x = 2
// Create references with &
const ref = &x

// Dereferencing is automatic
print(ref + 3) // 5

var y = 3
// Create variable references with &var
var yref = &var y
yref = 2

// You cannot reference a reference
const refref = &&x // Error!
// ...Or an rvalue
const rvref = &2 // Error!

// Reference types: &T/&var T
fun add(a int, b int, target &var int):
    target = a + b
end

// Subscripting a variable array returns a variable reference
var arr = [1, 2, 3, 4, 5]
arr[0] = 2 // arr = [2, 2, 3, 4, 5]

// Unless the array is const, of course
const carr = [1, 2, 3, 4, 5]
carr[0] = 2 // Error: Cannot assign to a const reference!

// Same applies for variable structs
struct Person:
    name string
    age int
end

var jim = Person("Jim", 99)

// Accessing a struct member returns a reference
jim.age = 98

// Unless the struct is const, of course
const sam = Person("Sam", 42)
sam.age = 43 // Error: Cannot assign to a const reference!

// Variable references are implicitly convertible to const references, but not the other way around
fun printPerson(person &Person):
    print("Person("+person.name", "+string(person.age)+")")
end

printPerson(&var jim) // Works, but could be confusing
printPerson(&jim) // Better

fun jimmifyPerson(person &var Person):
    person.name = "Jim"
    person.age = 99
end

jimmifyPerson(&sam) // Cannot do this!

Add “fixed” variables

I always wanted other languages to have it, but i have found 0 languages with this feature.
Currently, in enact there’s currently only const,

but let me introduce you to the fixed ( or just fix ).
Basically it behaves like const before #68. Example with painting: So when the painting is fixed, you just can’t move it or put it somewhere else (assign to it), but when it’s constant, it is completely static and unchangeable, so you can’t even paint on the painting.
The syntax is the same as with const:

fixed list = [1, 2, 3]
list = [ 69, 42 ] // error
list[0] = 3 // :D

(heh this is #69)

Implement arrays for the backend

Arrays parse and analyse just fine, but right now, when you create or subscript an array, you get a compilation error:

[line 1] Error at '[':
    [1, 2, 3, 4, 5]
    ^
Not implemented.

I'd now like to resolve this by implementing array literals, array subscription and array assignment in the compiler and VM.

Modify AST/parser for new syntax

Now that the lexer is compatible with the new syntax, the AST and the parser must also be modified. Most of the statements from the old language have survived, just with different syntax. The most notable changes are as follows:

  • New block delimiters {}
  • given/when => switch/case
  • impl blocks instead of defining methods in type
  • Bitwise operators
  • Generics with [], no more array literals
  • Mandatory semicolons (a la Rust)
  • Most control flow statements are expressions
  • var/const => mut/imm
  • Explicit referencing with '&'
  • Optional types with '?'

Implement semantic analysis

The old analyser module needs to go, particularly given the significant language changes that have occurred. I did start working on a sema module; I intend to pick up where I left off with that.

One pass over the AST (as was conducted by analyser) will not suffice. The minimum number of passes I think are reasonable is somewhere around 3, which is unfortunate but necessary.

  • Collect impl blocks and associate them with structs
  • Declare all variables and types in the symbol table
  • Attempt to associate all symbols with a value

This should allow for declarations in any order. I'm considering experimenting with bidirectional type checking, so that generics are a bit more elegant. Consider:

func cast(x $From) $To => x as $To;
func takesAnInt(x int) int => x;

// Without bidirectional type checking
takesAnInt(cast(2.5) as int);

// With bidirectional type checking
takesAnInt(cast(2.5));

Improve code quality and performance

Issues as small as passing by value instead of reference to major design flaws in classes plague the code in this repository, and must be addressed.

This is the reference implementation of Enact, so first and foremost, it must work. But as a piece of code, it should also be correct, idiomatic and readable. More commenting needs to be done throughout the entire codebase.

Plus, it needs to run fast, without leaking memory. There's a long road ahead in terms of optimization that needs to be done.

It's certainly no easy feat, but I'm sure that over time, these issues can be gradually addressed and resolved.

Replace #define DEBUG_x with argv flags

I'd like to replace these compile-time options in common.h:

#define DEBUG_PRINT_AST
#define DEBUG_DISASSEMBLE_CHUNK
#define DEBUG_TRACE_EXECUTION
#define DEBUG_STRESS_GC
#define DEBUG_LOG_GC

...with runtime argv flags, e.g:

enact --debug-stress-gc script.en

All of the flags that precede the script filename will be passed to the Enact interpreter, and those that supersede it will be passed to the script itself.

Perhaps a --debug-enable-all flag too, to emulate #define DEBUG.

Change for loop syntax

The for loop, as it stands, is one of the ugliest parts of the language, mainly due to the use of the semicolon:

for var i = 1; i <= 20; i = i + 1:
    print(i)
end

I intend to slightly change the syntax by replacing the semicolons (;) with vertical separators (|) to remedy this:

for var i = 1 | i <= 20 | i = i + 1:
    print(i)
end

It looks and feels more modern and Enact-y.

Implement a copy operator

I've decided to move away from the references proposal described in #60, and instead pass Objects by reference by default.

To replace the added control that references would have added, I've decided to add a new copy operator, which acts like this:

struct Person:
    name string
    age int
end

fun setAgeTo99(people [Person]) int:
    each person in people:
        person.age = 99
    end
end

var people = [Person("Jim", 20), Person("Sam", 84), Person("Matt", 42)]

setAgeTo99(copy people)
// `people` in this scope is unaffected

setAgeTo99(people)
// `people` in this scope are now all 99

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.