SkillAgentSearch skills...

Monkey

Interpreter with support for class, linq, sql, net, http, fmt, json and A realtime syntax highlighting REPL.

Install / Use

/learn @haifenghuang/Monkey

README

Deprecation Notice

This project is no longer being maintained. All the contents have been moved to magpie.

Monkey Programming Language

Chinese version: 中文

Table of Contents

Summary

Monkey is a toy language interpreter, written in Go. It has C-style syntax, and is largely inspired by Ruby, Python, Perl and c# It support the normal control flow, functional programming and object oriented programming. It also has a REPL with realtime syntax highlighter.

This is a sample program using monkey language:


//Declare annotation class
//Note: In the body, you must use property, not method.
class @MinMaxValidator {
  property MinLength
  property MaxLength default 10 //Same as 'property MaxLength = 10'
}

//This is a marker annotation
class @NoSpaceValidator {}

class @DepartmentValidator {
  property Department
}

//The 'Request' class
class Request {
  @MinMaxValidator(MinLength=1)
  property FirstName; //getter and setter are implicit. It is equal to 'property FirstName { get; set; }'

  @NoSpaceValidator
  property LastName;

  @DepartmentValidator(Department=["Department of Education", "Department of Labors"])
  property Dept;
}

//This class is responsible for processing the annotation.
class RequestHandler {
  static fn handle(o) {
    props = o.getProperties()
    for p in props {
      annos = p.getAnnotations()
      for anno in annos {
        if anno.instanceOf(MinMaxValidator) {
          //p.value is the property real value.
          if len(p.value) > anno.MaxLength || len(p.value) < anno.MinLength {
            printf("Property '%s' is not valid!\n", p.name)
          }
        } elseif anno.instanceOf(NoSpaceValidator) {
          for c in p.value {
            if c == " " || c == "\t" {
              printf("Property '%s' is not valid!\n", p.name)
              break
            }
          }
        } elseif anno.instanceOf(DepartmentValidator) {
          found = false
          for d in anno.Department {
            if p.value == d {
              found = true
            }
          }
          if !found {
            printf("Property '%s' is not valid!\n", p.name)
          }
        }
      }
    }
  }
}

class RequestMain {
  static fn main() {
    request = new Request()
    request.FirstName = "Haifeng123456789"
    request.LastName = "Huang     "
    request.Dept = "Department of Labors"
    RequestHandler.handle(request)
  }
}

RequestMain.main()

Below is the result:

Property 'FirstName' not valid!
Property 'LastName' not valid!

Below is the REPL with real time syntax highlight:

REPL

Below is the html document generated using the mdoc tool:

HTML DOC

Overview

This project is based on mayoms's project monkey with some bug fixes and a lot of new features including:

  • Added simple class support(Indexer, operator overloading, property, static method/property/field and class annotation)
  • Modified string module(which can correctly handle utf8 character encoding)
  • Added file module(with some new methods).
  • Added mathtime, sort, os, log, net, http, filepath, fmt, sync, list, csv, regexp, template, etc...
  • sql(db) module(which can correctly handing null values)
  • flag module(for handling command line options)
  • json module(for json marshaling and unmarshaling)
  • linq module(Code come from linq with some modifications)
  • decimal module(Code come from decimal with some minor modifications)
  • Regular expression literal support(partially like perls)
  • channel support(like golang's channel)
  • more operator support(&&, ||, &, |, ^, +=, -=, ?:, ??, etc.)
  • utf8 support(e.g. you could use utf8 character as variable name)
  • more flow control support(e.g. try/catch/finally, for-in, case, c-like for loop)
  • defer support
  • spawn support(goroutine)
  • enum support
  • using support(like C#'s using)
  • pipe operator support(see demo for help)
  • function with default value and variadic parameters
  • list comprehension and hash comprehension support
  • user defined operator support
  • Using method of Go Package(RegisterFunctions and RegisterVars)

There are a number of tasks to complete, as well as a number of bugs. The purpose of this project was to dive deeper into Go, as well as get a better understanding of how programming languages work. It has been successful in those goals. There may or may not be continued work - I do plan on untangling a few messy spots, and there are a few features I'd like to see implemented. This will happen as time and interest allows.

Installation

Just download the repository and run ./run.sh

Basic use

To access the REPL, simply run the following:

~ » monkey
Monkey programming language REPL

>>

or, to run a program:

monkey path/to/file

Language Tour

Comments

Monkey support two kinds of single line comment and also block comment.

// this is a single line comment
# this is another single line comment

/* This is a 
   block comment.
*/

Data Types

Monkey supports 9 basic data types: String, Int, UInt, Float, Bool, Array, Hash, Tuple and Nil

s1 = "hello, 黄"       # strings are UTF-8 encoded
s2 = `hello, "world"`  # raw string
i = 10                 # int
u = 10u                # uint
f = 10.0               # float
b = true               # bool
a = [1, "2"]           # array
h = {"a": 1, "b": 2}   # hash
t = (1,2,3)            # tuple
n = nil

Constants(Literal)

In monkey, there are mainly eleven types of constants(Literals).

  • Integer
  • UInteger
  • Float
  • String
  • Regular expression
  • Array
  • Hash
  • Tuple
  • Nil
  • Boolean
  • Function
// Integer literals
i1 = 10
i2 = 20_000_000     //for more readable
i3 = 0x80           // hex
i4 = 0b10101        // binary
i5 = 0o127          // octal

// Unsigned Integer literals
ui1 = 10u
ui2 = 20_000_000u     //for more readable
ui3 = 0x80u           // hex
ui4 = 0b10101u        // binary
ui5 = 0o127u          // octal

// Float literals
f1 = 10.25
f2 = 1.02E3
f3 = 123_456.789_012 //for more readable

// String literals
s1 = "123"
s2 = "Hello world"

// Regular expression literals
r = /\d+/.match("12")
if (r) { prinln("regex matched!") }

// Array literals
a = [1+2, 3, 4, "5", 3]

// Hash literals
h = { "a": 1, "b": 2, "c": 2}

//Tuple literals
t = (1, 2+3, "Hello", 5)

// Nil literal
n = nil

// Boolean literals
t = true
f = false

// Function literals
let f1 = add(x, y) { return x + y }
println(f1(1,2))

//fat-arrow function literals
let f2 = (x, y) => x + y
println(f2(1,2))

Variables

Variables in Monkey could start with the keyword let, or nothing with the form variable=value.

let a, b, c = 1, "hello world", [1,2,3]
d = 4
e = 5
姓 = "黄"

You can also use Destructuring assignment. Note, the left-hand side must be included using the '()'.

//righ-hand side is an array
let (d,e,f) = [1,5,8]
//d=1, e=5, f=8

//right-hand side is a tuple
let (g, h, i) = (10, 20, "hhf")
//g=10, h=20, i=hhf

//righ-hand side is a hash
let (j, k, l) = {"j": 50, "l": "good"}
//j=50, k=nil, l=good

Note however, if you do not use the keyword let, you could not do mult

View on GitHub
GitHub Stars386
CategoryData
Updated9d ago
Forks20

Languages

Go

Security Score

100/100

Audited on Mar 20, 2026

No findings