a silly little language
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.
Go to file
bachkata d103bff62c implement int->string 12 months ago
aoc/day01 day1 part2 (without slices) 1 year ago
cipher s/input/read-line/ 12 months ago
libs initial commit of namespace support with 'use-as' 12 months ago
neighborcat finish neighborcat implementation 1 year ago
.gitignore gitignore pycache 1 year ago
README.md progress 6/5 1 year ago
exceptions.py clarify exception 12 months ago
interpreter.py implement int->string 12 months ago
lexer.py bugfix: support escaped double quotes in strings 12 months ago
neb.py add python3 shebang 12 months ago
parser.py refactor: better error messages 1 year ago
structs.py use an enum and a map for type hierarchy 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