# neb ### an attempt at a language ## ideas - **Lisp-y**: I hope you like parentheses! - **Strongly typed**: types are Good, and could enable future compilation - **We <3 Linux**: strong support for pipelines and shell-ing out - **Immutable variables**: mutability is scary and makes for strange bugs - **Pure functions**: side effects are also scary ## things that (hopefully) work ### housekeeping - TODO `(exit [[status :int]]) => :bool` ### io - `(print [out :string]) => :bool ; print to stdout` - TODO `(print-all [strings :list]) => :bool ; a list of strings` ### file system - `(glob [regex :string]) => :list` - `(read-lines [filename :string]) => :list` - `(unlink [filename :string]) => :list ; returns empty list on success` ### comparison and boolean - `(and [arg :bool] [many :bool]) => :bool` - `(or [arg :bool] [many :bool]) => :bool` - `(eq? [arg1 :literal] [arg2 :literal]) => :bool` - `(> [left :number] [right :number]) => :bool` - `(>= [left :number] [right :number]) => :bool` - `(< [left :number] [right :number]) => :bool` - `(<= [left :number] [right :number]) => :bool` - `(not [arg :bool]) => :bool` ### math - `(+ [arg :number] [many :number]) => :number` - `(- [arg :number] [many :number]) => :number` - `(* [arg :number] [many :number]) => :number` - `(/ [num :number] [denom :number]) => :number` ### string - `(concat [arg :string] [many :string]) => :string` - `(split [arg :string] [split-val :string]) => :list` - `(strip [arg :string]) => :string` ### flow control - `(if [cond :bool] [t-branch :any|:expr] [[f-branch :any|:expr]]) => :any` - `(for-count [count :int] [many :expr]) => :any ; creates 'idx' variable with loop count` - `(for-each [items :list] [many :expr]) => :any ; creates '_item_' variable with current item` - `(| [first :expr] [many :expr]) => :any ; creates 'items' variable` - `(branch ([cond1 :bool] [expr1 :any]) [([condN: :bool] [exprN :any])]) => :any` - `(block [expr1 :any] ... [exprN :any]) => :any` ### type checking - TODO `(string? [arg :any]) => :bool` - TODO `(int? [arg :any]) => :bool` - TODO `(float? [arg :any]) => :bool` - TODO `(number? [arg :any]) => :bool ; returns #true for :int or :float` - TODO `(bool? [arg :any]) => :bool` - `(list? [arg :any]) => :bool` ### type conversion - TODO `(int->string [arg :int]) => :string` - TODO `(float->string [arg :float]) => :string` - TODO `(number->string [arg :number]) => :string` - TODO `(bool->string [arg :bool]) => :string` - `(->string [arg :literal]) => :string ; works for all literals` - `(string->int [arg :string]) => :int` ### variables - `(def [name :string] [value :expr]) => ? ; lexically scoped` - `(redef [name :string] [value :expr]) => ? ; must already be defined` ### shell - `($ [command :string]) => :list ; doesn't support pipes, first item is return code` - TODO `($| [commands :list]) => :bool ; pipes together multiple shell commands` ### functions - `(lambda (args) (expr1) (expr2) ... (exprN)) => :any` - `(func name (args) (expr1) (expr2) ... (exprN)) => :any` ### lists - `(empty? [arg :list]) => :bool` - `(first [arg :list]) => :any ; car` - `(list [arg :any] [many :any]) => :list` - `(list-length [arg :list]) => :int` - `(list-reverse [arg :list]) => :int` - `(rest [arg :list]) => :any ; cdr` - `(shuf [arg :list]) => :list ; shuffle the elements of the list` - `(zip [arg1 :list] [arg2 :list]) => :list` ### "higher order" - `(apply [func :symbol] [target :list]) => :any` - `(map [func :symbol] [target :list]) => :list` ### other - pretty much nothing else ## TODO (this section may be incomplete) ### types - [ ] revisit type system when i understand *gestures broadly* ### parsing - [x] build an AST like a real person (sorta?) ### math - [x] division (float) - [x] division (int) - [ ] mod (int) - [ ] exponent ### strings - [x] concat - [ ] substring - [ ] lower/uppercase ### flow control - [x] if - [x] if with empty else - [x] branch - [x] pipe ### lists - [x] lex - [x] parse - [x] evaluate ### other structure things - [ ] generic struct? - [ ] dict? ### symbols - [x] define - [x] access ### shell - [x] call out - [x] pipe