GithubHelp home page GithubHelp logo

egranata / krakatau Goto Github PK

View Code? Open in Web Editor NEW
12.0 12.0 0.0 430 KB

Krakatau: a stack based virtual machine

License: Apache License 2.0

CMake 0.56% C++ 98.83% Lex 0.60%
cpp17 functional functional-programming stack virtual-machine

krakatau's People

Contributors

egranata avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar

krakatau's Issues

Ternary operation

It would be good to have iftrue <...> else <...> even if it is just a convenience operation

Allow a bind operation

Define an operation bind that creates a partial bind at runtime

The only tricky part about this is that "bind" is the name of a value type already, so it can't automagically just be the name of an operation for parsing purposes

Objects

One might consider having a table that contains a set of (name, value) pairs, some of which are data and other are operations (would it make sense to bind an operation to the value itself and put it into the table?)

Some kind of syntax sugar could be provided for "call one such operation", essentially making it a method call on an immutable object

Construction could happen via prototypes

Generate operation/value boilerplate from JSON

More of a long-term idea, but consider a JSON format where one can describe, e.g. the types of inputs to an operation, or the keywords that can generate a value type, if any, and have C++ code be automatically generated at build time from this description

Example programs

Write - and push - interesting sample programs using Krakatau

This has at least two separate purposes:

  • serves as documentation of the language;
  • helps discover areas where the language is not sufficient and/or clunky to use.

Rework operation class hierarchy

The current class model for Operation has a few nice properties:

  • most methods are silently implemented for operations with no extra payload;
  • failing to implement something when required is a compile-time error;
  • std::shared_ptr can be passed around as a common currency;
  • RTTI just works.

OTOH, it is fragile, hard to extend and relies extensively on macros.

It would be nice to keep these properties, but rework the model to allow new behaviors to be added in a more streamlined fashion.

Consider providing big numbers

Numbers are currently uint64_t

It might be interesting to provide big numbers. This would likely come at a performance cost, but it should be possible to offer a variant<> so that one only pays (most of) the cost if needed

Native operations

This is largely about the "tetris test".

Provide a way to invoke "native" operations, e.g. file or network access.

Partial bind

Given a block with N slots, allow defining a partial bind of that block. For example, given

value foo block slots $a,$b,$c,$d
...

one could do something like

load foo
push number 1
push empty
bind

to obtain a block in two slots $c,$d, such that calling bound_foo(3,4) would be equivalent to calling foo(1,empty,3,4) (except the order would be inverted, because slots are popped last-to-first)

Object model: a block is an operation

The object model around callable entities is more convoluted than it should be, having all separate objects for a bind vs. an operation vs. a block

In practice, operations are all that really exist and a bind/block should just be subclasses thereof

This would allow removing Value_Block and Value_Bind

At parse time, one would still check for bind and block and pick an appropriate subclass, but this should be no different than push vs. dup.

filter map and reduce should work on Iterables

Allow filter map and reduce to work on sets, and generally on all Iterable things

This would involve being able to - given a value of some iterable type - make a new value of that same type, and append things to it at runtime

Set type

This could be as simple as a convenience over table, so basically a table of values to boolean true for all elements in the set

Iterable values

Tuples, strings, tables and sets are "iterable", aka they contain other values that can be enumerated

Each operation that wants to act on this now needs to be extended to deal with different value types

There should be a common language of "iterable value" and looping over the elements of one

Enumerated types

Add support for enumerations, i.e. types whose value can be one of a closed set of symbolic constants

Bind operation is redundant

bind, the operation, is actually redundant.

What should actually happen is that, having a Value and a Value_Operation, one should pack them into a tuple, and then typecast the tuple to a Value_Bind

Easy argument count for operations

A lot of operation implementations have boilerplate of the form

    if (!s.stack().hasAtLeast(2)) {
        s.stack().push(Value::error(ErrorCode::INSUFFICIENT_ARGUMENTS));
        return Operation::Result::ERROR;
    }

This should somehow be automated such that one can just declare the argument count for an operation. There should be a provision for "unknown at compile time" and a provision for "completely unknown, will accept anything"

Additional value traits

In the same vein as IterableValue, there should be additional "value traits" that allow defining operations on classes of values.

Examples include: AppendableValue for values that one can append new values to (e.g. tables and tuples); FindableValue for values that one can search by key out of (e.g. sets and tables)

Operations for "this (tuple/table)" + "element"

Consider an operation that given (tuple, value) and (table, tuple (value, value)) would create a new tuple or table that contains everything in the previous container AND also the new element

slots could be typed

Consider allowing slots to have type hints on them, e.g.

slots number $a, string $b

which would introduce automated type checking and return a type error if the actual type does not match the declared type. This would have to be made optional, both in the sense that it need not exist, and in the sense that "any type is valid" should be allowed (coincidentally, the two would end up having the same semantics, but one might want an explicit any marker for documentation purposes)

Block slots

Define - immutable - named slots associated with a block's execution.

This would allow, for example, one to name the "arguments" to a block and then push them back onto the stack at any convenient time.

Detect stack overflow

A program such as

value main block {
    load main
    exec
}

will eventually cause a segfault

It would be nice to catch this somehow (probably via signals), and do something intelligent

Opaque native handles

There should be a way for a native operation to return an "opaque handle" value, such that its type could be checked for "valid" and "associated to this operation" or at least "associated to this native library"

This could for example be used for a native library that provides file access to return a file descriptor object

CALL operation

CALL would be a convenience operation, e.g.

call foo (number 1, number 2, boolean false)

Would be equivalent to

push number 1
push number 2
push boolean false
load foo
exec

This is not, in general, possible, but - if "foo" is already available at the "call" site, the assembler could check that the list of arguments if of the same size as the slots, and emit a warning if not.

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.