forked from mryouse/neb-python
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
12 months ago | |
---|---|---|
aoc/day01 | 1 year ago | |
cipher | 12 months ago | |
libs | 12 months ago | |
neighborcat | 1 year ago | |
.gitignore | 1 year ago | |
README.md | 1 year ago | |
exceptions.py | 12 months ago | |
interpreter.py | 12 months ago | |
lexer.py | 12 months ago | |
neb.py | 12 months ago | |
parser.py | 1 year ago | |
structs.py | 12 months ago |
README.md
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
(input [prompt :string]) => :string
(print [out :string]) => :bool ; print to stdout
file system
(exists? [filename :string]) => :bool
(glob [regex :string]) => :list
(read-lines [filename :string]) => :list
(unlink [filename :string]) => :list ; returns empty list on success
(with-write [filename :string] [[many :expr]]) => :any ; close file after block ends
(write [content :string] [file :handle(?)]) => :list ; not yet sure how to handle, uh, handles
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
(first-char [arg :string]) => :string
(concat [arg :string] [many :string]) => :string
(join [arg :list] [join-val :string]) => :string
(newline) => :string
(rest-char [arg :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
(while [cond :bool] [many :expr]) => :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
(append [arg :list] [value :any]) => :list
(empty? [arg :list]) => :bool
(first [arg :list]) => :any ; car
(in? [candidate :literal] [target :list]) => :bool
(last [arg :list]) => :any
(list [arg :any] [many :any]) => :list
(list-length [arg :list]) => :int
(list-reverse [arg :list]) => :int
(remove [arg :list] [key :literal]) => :list ; this is actually for records
(rest [arg :list]) => :any ; cdr
(shuf [arg :list]) => :list ; shuffle the elements of the list
(slice [arg :list] [start-idx :int] [[length :int]]) => :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
- build an AST like a real person (sorta?)
math
- division (float)
- division (int)
- mod (int)
- exponent
strings
- concat
- substring
- lower/uppercase
flow control
- if
- if with empty else
- branch
- pipe
lists
- lex
- parse
- evaluate
other structure things
- generic struct?
- dict?
symbols
- define
- access
shell
- call out
- pipe