Minim

From Esolang
Jump to: navigation, search

= Minim: A Simple, Low Level, Interpreted Language

Minim was

Minim

About

Minim is a simple, low-level, interpreted programming language designed by TheNewComposer as part of a final project for a college Java programming course. The original interpreter was then ported to Kotlin, to improve maintainability. The current version is in the fourth iteration of the language's syntax.

Syntax & Semantics

Minim is a imperative, procedural programming language which, true to it's name, is very minimalist in terms of functionality:

Comments

Line comments are marked by a semicolon, and can appear at any point on a line:

; This is a comment!

There are no block comments.

Values

In Minim, all operable values are bytes. Numeric literals can come in three styles:

Style Example
Binary 0b11001010
Decimal 202
Hexadecimal 0xCA

Other data types are simulated by conversions to bytes, in conjunction with appropriate operator semantics:

Type Examples
Boolean T, F
Character 'A', 'z', '\n'
String "Hello!"

Floating-point numbers are not supported.

Ranges

A range is a collection consisting of multiple bytes. A range literal is surrounded by curly braces, and the values are separated by commas:

{ 0, 1, 3, 7, 15, 31, 63, 127, 255 }

Preprocessor

Since the only values allowed in Minim are bytes, a preprocessor is used to convert all text literals into a form consisting only of numeric literals. Character literals are converted to a single numeric literal, while string literals are converted to a null-terminated range of numeric literals:

'A'     -> 65

'\n'    -> 10

"Minim" -> {77, 105, 110, 105, 109, 0}

Note that the boolean literals T and F are not preprocessed. They are simply lexed as byte literals inline.

Memory

All memory is stored in a one-dimensional, zero-indexed tape of bytes, and is accessed in a similar manner to an array. As such, there are no named variables. They simply have a position along the tape:

[42] ; Access the memory at index 42

Memory accessors can be nested:

[[69]] ; Access the memory at the index stored at index 69

As well as single value access, ranges can be accessed in any of three ways:

Style Example Get/Set Description
Fixed [0 : 3] Get/Set Access indices from 0 to 3 inclusive.
Relative [0 @ 3] Get/Set Access 3 indices starting from 0.
Lazy [0..] Set Only Access any amount of indices.

Operators

Most all standard operators are available, though some operate differently, due to the simplified type system:

Name Symbol
Add +
Subtract -
Multiply *
Divide /
Modulus %
Bit And &
Bit Or |
Exclusive Or ^
Bit Not ~
Left Shift <<
Right Shift >>
Unsigned Right Shift >>>
Assign =
Logical And &&
Logical Or ||
Logical Not !
Equal ==
Not Equal !=
Less <
Less Equal <=
Greater >
Greater Equal >=
Ternary ?:

When it comes to expected boolean operands, 0 is evaluated to false, and any other number evaluates to true.

Statements

All statements are one or more expressions terminated by a period:

<statement>.

Assignment

Used to place any number values into memory:

[42] = 69.

[0] = [1].

[0 : 3] = { 0, 1, 2, 3 }.

[13..] = "Lazy...".

Unsigned Input

Used to place an unsigned number from input into memory:

>+[0].

Unsigned Output

Used to write a byte, unsigned, to the console:

<+[0].

Signed Input

Used to place an signed number from input into memory:

>-[0].

Signed Output

Used to write a byte, signed, to the console:

<-[0].

ASCII Input

Used to place an ASCII character from input into memory:

>$[0].

ASCII Output

Used to write a byte, as ASCII, to the console:

<$[0].

Label

Used to define a goto label:

#0.

#'A'.

Goto

Used for control flow:

<#0.

<#'A'.

Example Programs

Hello World

; Hello World in Minim
[0] = 1.
[1..] = "Hello, World!\n".
#0.
  <$ [[0]].
  [0] = [0] + 1.
  <# [[0]] ? 0 : 1.
#1.

99 Bottles

; START 99 BOTTLES
[0] = 99.

#'['.
  <- [0].
  [1] = 2.
  [2..] = " bottles of beer on the wall,\n".
  #'A'.
    <$ [[1]].
    [1] = [1] + 1.
    <# [[1]] ? 'A' : 'a'.
  #'a'.

  <- [0].
  [1] = 2.
  [2..] = " bottles of beer.\n".
  #'B'.
    <$ [[1]].
    [1] = [1] + 1.
    <# [[1]] ? 'B' : 'b'.
  #'b'.

  <# [0] ? '+' : ']'.
  #'+'.

  [1] = 2.
  [2..] = "Take one down, pass it around,\n".
  #'C'.
    <$ [[1]].
    [1] = [1] + 1.
    <# [[1]] ? 'C' : 'c'.
  #'c'.

  [0] = [0] - 1.

  <- [0].
  [1] = 2.
  [2..] = " bottles of beer on the wall.\n\n".
  #'D'.
    <$ [[1]].
    [1] = [1] + 1.
    <# [[1]] ? 'D' : 'd'.
  #'d'.

  <#'['.
#']'.

[1] = 2.
[2..] = "Go to the store, buy some more,\n99 bottles of beer on the wall.\n".
#'E'.
  <$ [[1]].
  [1] = [1] + 1.
  <# [[1]] ? 'E' : 'e'.
#'e'.
; END 99 BOTTLES