Skip to content

Paradisia/Charactetic

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 

Repository files navigation

#Charactetic

Charactetic is a programming language that uses only a left and right characters as code. All other characters are considered comments.

It's forked from Parenthetic.

##Hello World

The following Charactetic program prints 'hello world', using 0 as left character and 1 as right:

00010101100100101110001001110001101010101010101100010100111000110101010101010101011
00011010101010101010101011111000101011001001010111000100110011011000110101010101010
10101010101010101010101010101010101010101010101010111100010011100010011001101100010
01110010010111000110101010101010111100010011001101100010011100100101110001101010101
11100010011001101100010011100100101110001101010101010101010101011110001001100110110
00100111001001011100011010101010101010101010111100010011001101100010011100100101110
00110101010101010101010101010101111001001010111000100110011011000100111001001011100
01101010101010101010101010101010101010101010101111000100110011011000100111001001011
10001101010101010101010101010101011110001001100110110001001110010010111000110101010
10101010101010101010101010111100010011001101100010011100100101110001101010101010101
010101011110001001100110110001001110010010111000110101011111

The following Charactetic program prints 'hello world' using • and ·:

•••·•·•··••·••·•···•••·••···•••··•·•·•·•·•·•·•··•••·•·••···•••··•·•·•·•·•·•·•·•·•··
•••··•·•·•·•·•·•·•·•·•·•·····•••·•·•··••·••·•·•···•••·••··••··•··•••··•·•·•·•·•·•·•
·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•····•••·••···•••·••··••··•··•••·•
•···••·••·•···•••··•·•·•·•·•·•·•····•••·••··••··•··•••·••···••·••·•···•••··•·•·•·•·
···•••·••··••··•··•••·••···••·••·•···•••··•·•·•·•·•·•·•·•·•·•·•····•••·••··••··•··•
••·••···••·••·•···•••··•·•·•·•·•·•·•·•·•·•·•····•••·••··••··•··•••·••···••·••·•···•
••··•·•·•·•·•·•·•·•·•·•·•·•·•·•····••·••·•·•···•••·••··••··•··•••·••···••·••·•···••
•··•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•····•••·••··••··•··•••·••···••·••·•··
·•••··•·•·•·•·•·•·•·•·•·•·•·•·•·•····•••·••··••··•··•••·••···••·••·•···•••··•·•·•·•
·•·•·•·•·•·•·•·•·•·•·•·•·•····•••·••··••··•··•••·••···••·••·•···•••··•·•·•·•·•·•·•·
•·•·•·•····•••·••··••··•··•••·••···••·••·•···•••··•·•·•·····

##Installation

  1. Clone the repo, which includes an interpreter written in Python 2.7:

    git clone git@github.com:cammckinnon/Charactetic.git

  2. Navigate to the Charactetic directory and run the interpreter by typing:

    python Charactetic.py

    It accepts code as input from standard input. Input is read until EOF is found, after which the output is written to the console.

  3. Or you can read input from a file like this:

    cat program.p | python Charactetic.py

##Syntax

Charactetic uses Lisp-style expressions, where parentheses enclose expressions:

Lfoo arg1 arg2R

Note that Charactetic programs with unmatched parentheses are invalid

###Integers

A sequence of n parenthesis sets can be used to represent the integer n. For example the following sequence could represent the number 3:

LR LR LR

In order to tell the interpreter that you want the sequence to represent an integer, you must pass it as an argument to the built-in LLRR macro. The macro acts like a function that accepts parenthesis sequences and returns integers. For example, the following program prints 3.0 to the console:

L
    integer macro
    LLRR
    3 sets of parentheses
    LR LR LR
R

Output: 3.0

Or equivalently:

LLLRR LRLRLRR

Output: 3.0

Note that it doesn't matter how the parentheses in the sequence are nested within each other. For instance the following Charactetic program prints 5.0 to the console:

LLLRR LLLRRR LR LR R

Output: 5.0

###Symbols

A symbol is a sequence of parentheses that corresponds to some data or a function. For example, the symbol for the built-in multiplication function is LRLLRR. Like with integers, there is a macro for interpreting parenthesis sequences as symbols. It is LR.

For example, the following Charactetic program prints 10 by using the multiplication function LRLLRR to multiply 5 times 2:

L
    multiply [note the use of the [] macro]
    LLR LRLLRRR

    2
    LLLRR LRLRR

    5
    LLLRR LRLRLRLRLRR
R

Output: 10.0

Equivalent Lisp code:

L* 2 5R

It is also possible to define your own symbols, using the built-in 'define' function, whose symbol is LRLR. For example, the following code defines LLRRLLRR as 6, then adds multiplies by 2 to get 12. Remember that all characters other than L and R characters are comments Lincluding [ and ]R.:

define [[]][[]] as 6
L
    define
    LLR LRLRR

    [[]][[]]
    LLR LLRRLLRRR
    
    6
    LLLRR LRLRLRLRLRLRR
R

[[]][[]] * 2
L
    multiply
    LLR LRLLRRR

    [[]][[]]
    LLR LLRRLLRRR

    2
    LLLRR LRLRR
R

Output: 12.0

Equivalent Lisp code:

Ldefine x 6R
L* x 2R

##Standard Library

Charactetic has a built-in standard library that is available by default Lno includes/library imports necessaryR:

###define Symbol: LRLR

For details on define and its usage, see the Syntax->Symbols section above.

###multiply, divide, subtract, add These math operations can be performed on one or more numbers. Here are their symbols:

  • subtract: LLRLRR
  • multiply: LRLLRR
  • divide: LLRRLR
  • add: LLRR. Note: You can also use add for concatenating characters/strings together Lsee the string section belowR.

Example:

L
    plus
    LLR LLRRR
    
    3
    LLLRR LRLRLRR

    6
    LLLRR LRLRLRLRLRLRR
R

Output: 9.0

Equivalent Lisp code:

L+ 3 6R

###lambda Symbol: LR

Facilitates anonymous functions. Here's an example where we use define and lambda to create a function that takes in a number and adds 1 to it:

define a [][][] as a function that
takes in a number n and returns n + 1
L
    define
    LLR LRLRR

    [][][]
    LLR LRLRLRR

    L
        lambda
        LLR LRR

        L
            n [[]][]
            LLR LLRRLRR
        R

        n + 1
        L
            plus
            LLR LLRRR
            
            n [[]][]
            LLR LLRRLRR

            1
            LLLRR LRR
        R
    R
R

7 + 1
L
    plus
    LLR LRLRLRR
    7
    LLLRR LRLRLRLRLRLRLRR
R

Output: 8.0

Equivalent Lisp code:

Ldefine f
  Llambda LnR
    L+ n 1RRR

Lf 7R

###equal

Symbol: LLRRLLRR

Takes in two arguments. If they are equal, the True primitive is returned. Otherwise the False primitive is returned.

Example:

[equal 2 2]
L
    equal
    LLR LLRRLLRRR
    2
    LLLRR LRLRR
    2
    LLLRR LLRRR
R

Output: True

Equivalent Lisp code:

Lequal? 2 2R

###<=

Symbol: LRLLRRLR

Takes in two numeric arguments a and b. If a <= b, the True primitive is returned. Otherwise the False primitive is returned.

Example:

[<= 3 4]
L
    <=
    LLR LRLLRRLRR
    3
    LLLRR LRLRLRR
    4
    LLLRR LLRRLLRRR
R

Output: True

Equivalent Lisp code:

L<= 3 4R

###if

Symbol: LRLRLR

Takes in three arguments: condition, then, and else. If condition is not false and not 0, the then argument is evaluated and returned. Otherwise, the else argument is evaluated and returned.

Example:

if 3 = 4, return 1, otherwise return 2
L
    if
    LLR LRLRLRR

    [equal 3 4]
    L
        equal
        LLR LLRRLLRRR
        3
        LLLRR LRLRLRR
        4
        LLLRR LLLRRRLRR
    R

    1
    LLLRR LRR
    2
    LLLRR LRLRR
R

Output: 2.0

Equivalent Lisp code:

Lif Lequal? 3 4R 1 2R

###not

Symbol: LRLLRLRR

If the argument is neither 0.0 nor False, True is returned. Otherwise, False is returned.

Example:

[not [equal 1 1]]
L
    not
    LLR LRLLRLRRR

    [equal 1 1]
    L
        equal
        LLR LRLLRRLRR
        1
        LLLRR LRR
        1
        LLLRR LRR
    R
R

Output: False

Equivalent Lisp code:

Lnot Lequal? 1 1RR

###cons

Symbol: LLLRRRLR

Takes in two arguments a and b and returns a pair La, bR.

Example:

L
    cons
    LLR LLLRRRLRR

    1
    LLLRR LRR

    2
    LLLRR LRLRR
R

Output: L1.0, 2.0R

Equivalent Lisp code:

Lcons 1 2R

###car

Symbol: LLLRRRLLRR

Given a pair La, bR, returns a.

Example:

L
    car
    LLR LLLRRRLLRRR

    L
        cons
        LLR LLLRRRLRR

        1
        LLLRR LRR

        2
        LLLRR LRLRR
    R
R

Output: 1.0

Equivalent Lisp code:

Lcar Lcons 1 2RR

###cdr

Symbol: LLLRRRLRLR

L
    cdr
    LLR LLLRRRLRLRR

    L
        cons
        LLR LLLRRRLRR

        1
        LLLRR LRR

        2
        LLLRR LRLRR
    R
R

Output: 2.0

Equivalent Lisp code:

Lcdr Lcons 1 2RR

###empty

Symbol: LLLRRR

empty exists to facilitate lists. We define a list as a pair such that applying cdr one or more times to the list will return empty. Note - empty is not a function; it can be accessed directly. When printed to the console, empty appears as LR.

Example:

LLR LLLRRRR

Output: LR

Equivalent Lisp code:

LlistR

###char

Symbol: LLRRLLRRLR

Accepts one integer argument, and returns the corresponding ascii character.

Example:

L
    char
    LLR LLRRLLRRLRR

    33 [ascii value for '!']
    LLLRR LRLRLRLRLRLRLRLRLRLR
          LRLRLRLRLRLRLRLRLRLR
          LRLRLRLRLRLRLRLRLRLR
          LRLRLRR
R

Output: !

###string

Symbol: LLRRLRLLRR

Accepts a list of characters, and returns a string. string is useful for displaying messages.

Example:

define 97 for easy access to a and b
L   define
    LLR LRLRR
    97
    LLR LLRLRRR
    [+ 7 [* 9 10]]
    L
        LLR LLRRR
        LLLRR LRLRLRLRLRLRLRR
        L
            LLR LRLLRRR
            LLLRR LRLRLRLRLRLRLRLRLRR
            LLLRR LRLRLRLRLRLRLRLRLRLRR
        R
    R
R

[string ['a', ['b', []]]]
L
    string
    LLR LLRRLRLLRRR
    L   
        cons
        LLR LLLRRRLRR
        a
        L
            LLR LLRRLLRRLRR
            L   
                LLR LLRRR
                LLLRR R
                LLR LLRLRRR
            R
        R

        L   
            cons
            LLR LLLRRRLRR
            b
            L
                LLR LLRRLLRRLRR
                L   
                    LLR LLRRR
                    LLLRR LRR
                    LLR LLRLRRR
                R
            R
            empty
            LLR LLLRRRR
            
        R
    R   
R

Output: ab

Tip: You can also pass any combination of characters and strings into the add function Lsee aboveR to create strings.

##Error handling

If your program has a runtime error or a compiletime error the interpreter will print "Parenthesis Mismatch" to standard output and then exit.

##Test Suite

In the ./tests folder there is a series of tests that check the interpreter for correctness.

    python tests.py

You may find this useful if you wish to modify the interpreter's source code.

##Inspiration

This language was inspired by a conversation with [Lucas]Lhttp://www.lucaswoj.comR, who said that scheme looks like this: LRRLRLRLRRRRRLR. Well, it does now!

Also the esoteric language [Parenthesis Hell]Lhttp://esolangs.org/wiki/Parenthesis_HellR was a great inspiration.

About

A Lisp-style language whose programs consist entirely of parenthesis. Or any other characters.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published