public
Description: Hongmini is the programming language to embed in C++ programs.
Homepage:
Clone URL: git://github.com/dahlia/hongmini.git
name age message
file .gitignore Loading commit data...
file Makefile
file README.markdown
file hongmini.cpp
file hongmini.hpp
README.markdown

Hongmini Programming Language

Hongmini is the programming language to embed in C++ programs. If you want cooler embeddable programming language, there are Lua and Io.

Do not write serious programs in this language. Its implementation is not and won’t be optimized, so, too slow. Use it to embed only while you are writing a big C++ program and it should have various small plug-in programs.

Origin Of Language’s Name And Author

It is written by Hong MinHee. (This name is Korean style. You should write Hong first, but it is not given name but family name.) Naming the language bothers the author, so he named it casually: Hongmini. It is small and useless. The word ‘mini’ befits it, and the name ‘MinHee’ is pronounced like ‘mini’ in Korean.

Functions

There are 5 built-in types in Hongmini.

  • function
  • boolean (true, nil)
  • string
  • list
  • map

Every type is derived from function type, so all values are like function. Actually there are no types; there are only functions, just behave as other types.

Following code defines some functions.

abs <- (number): (number < 0)("-1", 1) * number

max <- (numbers...): {
  top <- numbers(0)
  numbers.each (number): {
    top <- (top > number)(top, number)
  }
  top
}

You may be able to infer some interesting rules.

  • The assignment operator is not =, but <-.

  • No function definition; However, you can assign function values to variable name, like JavaScript, Lua. Lambda the ultimate!

  • Two literal types. General function literal (block), and string literal. For example, 123 same as "123".

  • When boolean values are called, they behave like trinary operator in the other well-known languages such as C and Java.

  • There’s no specific number type. Instead, it can use arithmetic operators like +, * with string values.

  • Instead of the return keyword in other languages, it just returns last expression of function block, in similar way to Lisp dialects.

Lambda And Lexical Closure

All values are functions and all functions are values in the Hongmini programming language. To call function generally, you should name it. ‘Naming’ in computer programming means assignment or binding.

add <- (x, y): x + y

We can call evaluating (x + y) add(x, y). After this naming, add(3, 9) means (3 + 9) viz. 12. Functions can be more complex and longer.

multiply <- (x, y): {
  result <- 0; i <- 0
  loop (): {
    result <- add(result, x)
    i <- i + 1; i <= y
  }
  result
}

When the function contains two or more expressions, curly brackets should wrap its body, and EOL or semicolon separates each expression.

However, above code is a just example. You can multiply easily by *.

multiply <- (x, y): x * y

Omitting Parentheses In Function Call

You can omit parentheses in function call when possible and readable. Following two codes share the same behavior.

func 1, 2, 3
func(1, 2, 3)

However you cannot omit it when there are no arguments to pass into func. Following expression returns func itself, not the value in the calling func.

func

If you want to call func without any arguments, a pair of parentheses should be explicit.

func()

Omitting parentheses of function’s arguments makes calling higher-order function and applying function with list or dictionary prettier.

# function with list and dictionary
func []
func [1, 2, 3]
func {}
func { a <- 1; b <- 2 }

# higher-order function
map (filter [1, 2, 3, 4], (x): x % 2 == 1), (x): {
  log(x & "\n")
}

Pseudo-attributes And Pseudo-methods

Hongmini programming language has no attributes. It is just syntactic sugar for calling function. Following two expressions are the same.

function.attribute
function("attribute")

In other words, all function call can be also attribute accessor of the object. Likewise setting attribute is translated into calling function. The name of attribute passes into first parameter and value to set passes into second it.

function.attribute <- value
function("attribute", value)

You can apply this feature to imitate object’s method call. It will behave as higher-order function.

object.method()
object("method")()

You can use non-negative numeral as the name of attributes also.

list.0           # list(0)
list.0 <- value  # list(0, value)

Pseudo-operators

There are no operators in Hongmini programming language. However, pseudo-methods call can seem to use operators. Following expressions are the same.

value operator operand
value.operator(operand)
value("operator")(operand)

The psuedo-operator syntax can be used only when just one argument passes into method.

String Literal

There are two types of the string literal in Hongmini programming language.

  • double quotation
  • numeric string

The double quotation string literal is a widely used way to represent string values. It can contains any characters except double quotation character.

"To be, or not to be."
"1234"
"!@#@!#@!#"

"string with
a line break"

To contain double quotation character, it should be escaped with backslash.

"Lin Chi said, \"If you meet the Buddha on the road, kill him.\""

The numerical string literal is used usually to repreent number. Because there’s no specific number types in Hongmini programming language. However, 123 equals "123".

42
3.14159265

List And Map

To contain one or more values, you can use containers. There are two built-in container types.

  • ordered list, e.g. [], [1, 2, 3], ["hello", [1, 2], (x): x + 1]
  • map of string keys and values, e.g. { name <- "Hong, MinHee"; age <- 20 }

Lists have index numbers each element which starts from 0, and, it does’t limit the number of elements. It accepts any type.

list <- ["a", "b", "c", [1, 2, 3]]

You can count the number of elements in the list. Use pseudo-attribute size.

list.size

To iterate the list, use psuedo-method each. This method is higher-order function, and, function to pass to its parameters should accept one or two arguments: value and optional index number of element.

list.each (value): stdout.write(value & "\n") # it prints elements of list

list.each (value, index): {            # it prints elements and its index
  stdout.write(index & ". " & value)   # of list
  stdout.write("\n")
}

If you need for-like loop of C/C++, use function range. It generates a list that contains sequential numbers. It is equal to the function of the same name in Python.

range(5)        # [0, 1, 2, 3, 4]
range(3, 7)     # [3, 4, 5, 6]
range(2, 12, 3) # [2, 5, 8, 11]

range(1, 10) each stdout.write # it prints: 123456789

Maps have keys of string and its values. The key and its value are called “pair”, and you can translate pairs of the map to the two-dimensional list by function pairs.

name <- { family <- "Hong"; given <- "MinHee" }
pairs(name) # [["family", "Hong"], ["given", "MinHee"]]

There are keys and values also.

keys(name)   # ["family", "given"]
values(name) # ["Hong", "MinHee"]

There is no order in the map, so, order of the list which returned by pairs, keys and values depend on implementation.

Comments

# This line is ignored.

###
This area is
also ignored.
###

BNF

<program>      ::= { <expr> <terminate> } [ <expr> ]
<termiate>     ::= ( ";" | <newline> ) [ <terminate> ]
<expr>         ::= "(" <expr> ")"
                 | <literal>
                 | <lvalue>
                 | <func-call>
                 | <op-call>
                 | <assign>
<literal>      ::= <str-literal>
                 | <dict-literal>
                 | <func-def>
                 | <list-literal>
<str-literal>  ::= /"([^"]|\\.)*"/
                 | <number>
<number>       ::= /\d+/
<dict-literal> ::= "{" <program> "}"
<func-def>     ::= "(" <params> ")" ":" <dict-literal>
<list-literal> ::= "[" { <expr> "," } [ expr [ "," ] ] "]"
<lvalue>       ::= <id>
                 | <attr>
<id>           ::= /[^[:digit:][:space:]][^[:space:]]*/ except "<-"
<attr>         ::= <expr> "." ( <id> | <number> )
<func-call>    ::= <expr> "(" <args> ")"
                 | <expr> <args>
<args>         ::= { <expr> "," } [ <expr> [ "," ] ]
<op-call>      ::= <expr> <id> <expr>
<assign>       ::= <lvalue> "<-" <expr>