cozy

command module
v0.10.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2022 License: MIT Imports: 13 Imported by: 0

README

cozy

Abandoned

This was a fun project to help me learn more about PLD and Go, but I don't really have much time for it or interest in it anymore. You are more than welcome to fork it, or check out ABS which accomplishes many of the same goals and has an active developer community.


Simple interpreted programming language for similar use-cases as Python and Node. Meant to be cozy no matter what languages you already know.


This is a WIP. See the TODO.

Support with PayPal Patreon ko-fi

cozy (always spelled all-lowercase) is a simple, medium-to-high-level, interpreted, general purpose programming language. It can be used for many of the same tasks as shell scripts, Python, Node, and Ruby. It's dynamically and strongly typed, with some with features that work well with pseudo-functional programming but C-language-family syntax. There are no OOP constructs like classes; instead we have first-class functions, closures, plain data structures, and file-based modules.

It's meant to feel comfortable and familiar no matter what languages you might already know (hence the name). Performance isn't an explicit goal, but cozy is fairly fast (time the examples and try a benchmarking tool against the http server if you're curious). It's also meant to have a relatively simple host-language implementation (for example, much of the standard libarary is written in cozy itself) to make debugging easy and porting to other host languages in the future straightforward.

Example

# contrived example to show off some features and syntax; see the ./examples
# directory for more.
# reduce is a built-in method on arrays, int? is a built-in type checking
# function, and sum is a built-in method on arrays, but this example shows
# how they might be implemented by a user.

# let is for immutable variables
let reduce = fn (fun, xs, init) {
    # mutable is only available within blocks, not at at the top level
    mutable acc = init

    foreach i, x in xs {
        acc = fun(x, acc, i)
    }

    return acc
}

# identifiers can have unicode (for example, chinese characters),
# and question marks
let ints? = fn (xs) {
    foreach x in xs {
        # util is a builtin module
        if util.type(x) != "integer" && util.type(x) != "float" {
            return false
        }
    }

    # returns can be implicit (without the `return` keyword)
    true
}

let sum = fn (xs) {
    # basic assertions and a TAP-producing test library are built in
    util.assert(ints?(xs), "expected only numbers!")
    return reduce(
        fn (x, acc) {
            return x + acc
        }, xs, 0)
}

# only one level of equality checking, unlike JS's == vs ===
print(sum([1, 2, 3, 4]) == 10) # true

For more examples and documentation, see the examples and stdlib directories. The examples also serve as a second test suite. For vim, CLOC, and Ctags support, see the editor directory. Screenshot in vim:

vim plugin

About

Originally designed by writing a bunch of examples and a small stdlib. Implementation started as a fork from skx's version of the language from the Go Interpreters Book, and also includes some pieces of prologic's upstream version and ABS, among others (see comments). The differences between cozy and Monkey are too numerous to list here; it's best to think of it as a totally separate language. It's written in pure Go with minimal third-party dependencies, with a large amount of the standard library implemented in cozy itself.

This is the first large Go program I've worked on, so contributions, especially in areas where I didn't write idiomatic Go, are definitely welcome. See CONTRIBUTING for contribution guidelines.

Usage

Clone the repo and run make, and either copy the binary to somewhere in your path or run make install. Write some code (see the examples), and run cozy ./your-code.cz. You can also run without a specified file, in which case your entered code will be evaluated when you exit with ctrl+d.

Important Notes
  • print adds an ending newline, use or sys.STDOUT/sys.STDERR for raw text
  • No undefined or uninitialized variables Comments are Python/Shell style Errors
  • are values, so you can pass them around and use panic (like in Go) Using
  • set and delete on hashes returns a new hash let is for immutable
  • variables; mutable is for mutable ones; this is because setting mutable variables should be more annoying to do than setting mutable ones.
  • Uses Go's GC; porting to a different language might require writing a new GC.
  • Semicolons are optional Most statements are expressions, including if/else;
  • this also means implicit returns (without the return keyword) are possible
  • No top level mutable variables, because all top level variables are exported
  • Parens and braces are optional in for, foreach, and if expressions, as long as what would be between them is only one expression (would normally be typed on one line)
  • No ternary expressions, switch statements, or pattern matching; if statements are expressions and type-checking is dynamic, so there's no need for extra keywords or syntax
  • REPL history is stored at $HOME/.cozy_history, and the size (in lines) can be configured with the env var COZY_HISTSIZE
  • REPL config is stored at $HOME/.cozy_init and can contain any valid cozy code
Builtins

Global functions:

  • error creates a new error object
  • import imports another cozy file as a module
  • panic prints an error contents and exits
  • print Write values to STDOUT with newlines

Builtin modules (see examples for docs):

  • core
  • fs
  • http
  • json
  • math
  • net
  • sys
  • time
  • util

See also the standard library (written mostly in cozy itself).

Code Style

cozy doesn't care about formatting. You can use two spaces, four spaces, seventeen spaces, three spaces and a tab, or whatever. Semicolons are also optional in most cases (similar to the rules in JavaScript), and parenthesis and curly braces are also optional in conditions and loops.

The semi-official style which should be followed when submitting changes is fairly obvious from the examples and standard library:

  • Four spaces to indent
  • Use a space between identifiers and operators, with the exception of mutating postfix operators
  • Use a space between the fn keyword and opening paren
  • Use a space between opening/closing parens and opening/closing braces
  • Docstrings should be at the top of the function
  • Imports should be at the top of the module
  • Line length should not exceed 80 characters
  • Semicolons should not be used except in ambiguous situations
  • Identifiers should use snake_case

License

This code is licensed MIT. I've used code from various Monkey implementations, which are usually licensed MIT. Other code used in cozy includes comments with notes on the licenses.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
Package ast contains the definitions of the abstract-syntax tree that our parse produces, and our interpreter executes.
Package ast contains the definitions of the abstract-syntax tree that our parse produces, and our interpreter executes.
Package evaluator contains the core of our interpreter, which walks the AST produced by the parser and evaluates the user-submitted program.
Package evaluator contains the core of our interpreter, which walks the AST produced by the parser and evaluates the user-submitted program.
Package lexer contains the code to lex input-programs into a stream of tokens, such that they may be parsed.
Package lexer contains the code to lex input-programs into a stream of tokens, such that they may be parsed.
Package object contains our core-definitions for objects.
Package object contains our core-definitions for objects.
Package parser is used to parse input-programs written in cozy and convert them to an abstract-syntax tree.
Package parser is used to parse input-programs written in cozy and convert them to an abstract-syntax tree.
Package token contains constants which are used when lexing a program written in the cozy language, as done by the parser.
Package token contains constants which are used when lexing a program written in the cozy language, as done by the parser.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL