Introduction

FeInt is a stack-based, bytecode-style VM/interpreter written in Rust. It's a learning project and a work in progress and is not meant for production use.

Here's what a simple function definition looks like:

raise = (x, p) => x ^ p

Getting Started

Prerequisites

  1. Install Rust and Cargo

  2. Clone the feint repo:

    git clone git@github.com:feint-lang/feint.git
    

Running

Once you've installed Rust and cloned the FeInt repo as documented in the prerequisites section, you can run FeInt using Cargo:

# Run the REPL
cargo run

# Run a script
cargo run examples/fib.fi

Installation

Once you've installed Rust and cloned the FeInt repo as documented in the prerequisites section, you can install the feint executable:

cargo install --path .

By default, this will install feint into ~/.cargo/bin.

Types

Builtin Types

Basic

  • Type: The top of the type hierarchy
  • Always: Singleton @ that always evaluates to true
  • Bool: true and/or false
  • Float: Floating point numbers backed by Rust's f64
  • Int: Arbitrarily large integers
  • Nil: Singleton nil object representing the lack of any value
  • Str: String 'abc' or "abc"

Container

  • List: Mutable sequence of objects ["a", "b", "c"]
  • Map: Mutable map/dict {"a": 1, "b": 2}
  • Tuple: Immutable sequence of objects (1, 2, 3)

Function

  • BuiltinFunc: A FeInt function implemented in Rust
  • Func: A "user" function implemented in FeInt f = () => nil
  • Closure: An enclosure for a Func
  • BoundFunc: Binds a function to a this object

Errors

  • Err
  • ErrType

Files

  • File

Other

  • Cell
  • Iterator
  • Module
  • Prop (currently unused, may not be needed)

Custom Types

Custom types are not yet implemented. The proposed implementation will look something like this (with some details still be worked out):

MyType = () =>

    # NOTE: The @ prefix indicates class method.
    @new = (value) =>
        "Creates a new instance of this type."
        this.value = value

    + = (other) =>
        "Overloads the `+` operator for this type."
        MyType(this.value + other.value)

    !! = () =>
        "Returns the bool value of the object, if applicable."
        this.value > 10

    # NOTE: The $ prefix indicates a special method, similar to
    #       dunder methods in Python (e.g., `__str__`)
    $str = () =>
        "Returns the string representation of the object."
        $"{this.value}"

obj1 = MyType.new(1)
obj2 = MyType.new(2)
obj1 + obj2
# -> 3

Syntax

TODO

Operators

Unary Prefix

Unary operations of the form <operator><operand>. The result type varies on the operand type.

OperatorDescription
+Return value of operand (this essentially a no-op)
-Return negated value of operand

Boolean Prefix

Boolean prefix operators may only be applied to objects that can be converted to Bool. Currently, this includes Bools and nil only.

OperatorDescription
!Boolean NOT
!!Convert to Bool

Binary

Binary operations of the form LHS <operator> RHS. The result type varies on the operand types.

OperatorDescription
^Power
*Multiplication
/Division
//Floor division
%Modulus
+Addition
-Subtraction
.Attribute lookup

Comparisons

Binary operations of the form LHS <operator> RHS. The result is always a Bool.

OperatorDescription
$$Is/identity
$!Is not
===Type-equal
!==Not type-equal
==Equal
!=Not equal
<Less than
<=Less than or equal
>Greater than
>=Greater than or equal

Boolean

Binary operations of the form LHS <operator> RHS that may only be applied to objects that can be converted to Bool. The result is always a Bool. These operators are short-circuiting, so RHS will only be evaluated if necessary.

OperatorDescription
&&AND
||OR

Nil OR

OperatorDescription
??LHS if LHS is not nil, RHS otherwise

In Place

Binary operations of the form LHS <operator> RHS where LHS is something that can be assigned to. The result of the corresponding binary operation is assigned to LHS.

OperatorDescription
*=
/=
+=
-=