Remove old code.
This commit is contained in:
parent
3f7adea56f
commit
f5265a2287
|
|
@ -1,45 +0,0 @@
|
|||
#[
|
||||
|
||||
Copyright © 2021 Simon Forman
|
||||
|
||||
This file is part of Bliss
|
||||
|
||||
Bliss is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bliss is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bliss. If not see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
]#
|
||||
import streams, strutils, fp, reader, types
|
||||
|
||||
proc add_def(def: string, dictionary: var JoyMapType) =
|
||||
let d = read_str(def)
|
||||
let sym = d.head
|
||||
case sym.kind:
|
||||
of joyAtom:
|
||||
dictionary = dictionary + (sym.atomVal, d.tail)
|
||||
else:
|
||||
raise newException(ValueError, def)
|
||||
|
||||
proc defs_file2dict(defs_filename: string = "defs.txt"): JoyMapType =
|
||||
var strm = newFileStream(defs_filename, fmRead)
|
||||
var dictionary = newMap[string, JoyListType]()
|
||||
var line = ""
|
||||
if not isNil(strm):
|
||||
while strm.readLine(line):
|
||||
if line.isEmptyOrWhitespace:
|
||||
continue
|
||||
add_def(line, dictionary)
|
||||
strm.close()
|
||||
return dictionary
|
||||
|
||||
var dictionary* = defs_file2dict()
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
#[
|
||||
|
||||
Copyright © 2021 Simon Forman
|
||||
|
||||
This file is part of Bliss
|
||||
|
||||
Bliss is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bliss is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bliss. If not see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
]#
|
||||
import rdstdin, bigints, fp, printer, reader, types, joylib, utils, defs
|
||||
|
||||
|
||||
# Handle Ctrl-C by raising an IOError to break out of the mainloop
|
||||
# without waiting for the user to press enter.
|
||||
proc ctrlc() {.noconv.} =
|
||||
raise newException(IOError, "Got Ctrl-C, bye!")
|
||||
|
||||
setControlCHook(ctrlc)
|
||||
|
||||
|
||||
proc joy_eval(sym: string, state: var JoyState): JoyState =
|
||||
case sym
|
||||
|
||||
# Integer Math
|
||||
|
||||
of "+": push_int(pop_int(state) + pop_int(state), state)
|
||||
of "*": push_int(pop_int(state) * pop_int(state), state)
|
||||
of "-":
|
||||
let tos = pop_int(state)
|
||||
push_int(pop_int(state) - tos, state)
|
||||
of "/":
|
||||
let tos = pop_int(state)
|
||||
push_int(pop_int(state) div tos, state)
|
||||
of "%":
|
||||
let tos = pop_int(state)
|
||||
push_int(pop_int(state) mod tos, state)
|
||||
|
||||
# Comparision
|
||||
|
||||
of "<":
|
||||
let tos = pop_int(state)
|
||||
let second = pop_int(state)
|
||||
push_bool(second < tos, state)
|
||||
of ">":
|
||||
let tos = pop_int(state)
|
||||
let second = pop_int(state)
|
||||
push_bool(second > tos, state)
|
||||
of "<=":
|
||||
let tos = pop_int(state)
|
||||
let second = pop_int(state)
|
||||
push_bool(second <= tos, state)
|
||||
of ">=":
|
||||
let tos = pop_int(state)
|
||||
let second = pop_int(state)
|
||||
push_bool(second >= tos, state)
|
||||
of "=":
|
||||
let tos = pop_int(state)
|
||||
let second = pop_int(state)
|
||||
push_bool(second == tos, state)
|
||||
of "<>":
|
||||
let tos = pop_int(state)
|
||||
let second = pop_int(state)
|
||||
push_bool(second != tos, state)
|
||||
|
||||
# Boolean logic
|
||||
|
||||
of "and": # Have to pop, Nim `and` short-circuits.
|
||||
let tos = pop_bool(state)
|
||||
let second = pop_bool(state)
|
||||
push_bool(tos and second, state)
|
||||
of "or": # Have to pop, Nim `or` short-circuits.
|
||||
let tos = pop_bool(state)
|
||||
let second = pop_bool(state)
|
||||
push_bool(tos or second, state)
|
||||
|
||||
# Built-in Functions and Combinators
|
||||
|
||||
of "bool": truthy(state)
|
||||
of "branch": branch(state)
|
||||
of "clear": clear(state)
|
||||
of "concat": concat(state)
|
||||
of "cons": cons(state)
|
||||
of "dip": dip(state)
|
||||
of "dup": dup(state)
|
||||
of "first": first(state)
|
||||
of "i": i(state)
|
||||
of "loop": loop(state)
|
||||
of "pop": pop(state)
|
||||
of "rest": rest(state)
|
||||
of "stack": stack(state)
|
||||
of "swaack": swaack(state)
|
||||
of "swap": swap(state)
|
||||
|
||||
else:
|
||||
let def = dictionary.get(sym)
|
||||
if def.isEmpty:
|
||||
raise newException(ValueError, "Unknown: " & sym)
|
||||
state.expression = def.get() ++ state.expression
|
||||
state
|
||||
|
||||
|
||||
proc joy(state: var JoyState) =
|
||||
while not state.expression.isEmpty:
|
||||
# echo print_stack(state.stack), " . ", print_expression(state.expression)
|
||||
let term = state.expression.head
|
||||
state.expression = state.expression.tail
|
||||
case term.kind
|
||||
of joyInt, joyList, joyTrue, joyFalse:
|
||||
state.stack = term ^^ state.stack
|
||||
of joyAtom:
|
||||
state = joy_eval(term.atomVal, state)
|
||||
of joyParseError:
|
||||
echo term.errorMessage
|
||||
break
|
||||
|
||||
|
||||
|
||||
var state0: JoyState = (stack: Nil[JoyType](), expression: Nil[JoyType]())
|
||||
var state: JoyState
|
||||
while true:
|
||||
try:
|
||||
let e = read_str(readLineFromStdin("joy? "))
|
||||
state = (stack: state0.stack, expression: e)
|
||||
except IOError:
|
||||
break
|
||||
try:
|
||||
joy(state)
|
||||
except:
|
||||
echo getCurrentExceptionMsg()
|
||||
echo print_stack(state0.stack)
|
||||
continue
|
||||
echo print_stack(state.stack)
|
||||
state0 = state
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
#[
|
||||
|
||||
Copyright © 2021 Simon Forman
|
||||
|
||||
This file is part of Bliss
|
||||
|
||||
Bliss is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bliss is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bliss. If not see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
]#
|
||||
import bigints, fp, types, utils
|
||||
|
||||
proc branch*(state: var JoyState) =
|
||||
let true_body = pop_list(state)
|
||||
let false_body = pop_list(state)
|
||||
if pop_bool(state):
|
||||
state.expression = true_body ++ state.expression
|
||||
else:
|
||||
state.expression = false_body ++ state.expression
|
||||
|
||||
proc clear*(state: var JoyState) =
|
||||
state.stack = Nil[JoyType]()
|
||||
|
||||
proc concat*(state: var JoyState) =
|
||||
let tos = pop_list(state)
|
||||
let second = pop_list(state)
|
||||
push_list((second ++ tos), state)
|
||||
|
||||
proc cons*(state: var JoyState) =
|
||||
let tos = pop_list(state)
|
||||
let second = pop_any(state)
|
||||
push_list((second ^^ tos), state)
|
||||
|
||||
proc dip*(state: var JoyState) =
|
||||
let body = pop_list(state)
|
||||
let tos = pop_any(state)
|
||||
state.expression = body ++ tos ^^ state.expression
|
||||
|
||||
proc dup*(state: var JoyState) =
|
||||
if state.stack.isEmpty:
|
||||
raise newException(ValueError, "Cannot dup empty stack.")
|
||||
state.stack = state.stack.head ^^ state.stack
|
||||
|
||||
proc first*(state: var JoyState) =
|
||||
let tos = pop_list(state)
|
||||
if tos.isEmpty:
|
||||
raise newException(ValueError, "Cannot take first of empty list.")
|
||||
state.stack = tos.head ^^ state.stack
|
||||
|
||||
proc i*(state: var JoyState) =
|
||||
let body = pop_list(state)
|
||||
state.expression = body ++ state.expression
|
||||
|
||||
proc loop*(state: var JoyState) =
|
||||
let tos = pop_any(state)
|
||||
case tos.kind:
|
||||
of joyList:
|
||||
if pop_bool(state):
|
||||
state.expression = tos.listVal ++ tos ^^ j_loop ^^ state.expression
|
||||
else:
|
||||
raise newException(ValueError, "Loop body not a list.")
|
||||
|
||||
proc pop*(state: var JoyState) =
|
||||
if state.stack.isEmpty:
|
||||
raise newException(ValueError, "Cannot pop empty stack.")
|
||||
state.stack = state.stack.tail
|
||||
|
||||
proc rest*(state: var JoyState) =
|
||||
let tos = pop_list(state)
|
||||
if tos.isEmpty:
|
||||
raise newException(ValueError, "Cannot take rest of empty list.")
|
||||
push_list(tos.tail, state)
|
||||
|
||||
proc stack*(state: var JoyState) =
|
||||
push_list(state.stack, state)
|
||||
|
||||
proc swaack*(state: var JoyState) =
|
||||
let tos = pop_list(state)
|
||||
let stack = state.stack
|
||||
state.stack = tos
|
||||
push_list(stack, state)
|
||||
|
||||
proc swap*(state: var JoyState) =
|
||||
let tos = pop_any(state)
|
||||
let second = pop_any(state)
|
||||
state.stack = second ^^ tos ^^ state.stack
|
||||
|
||||
proc truthy*(state: var JoyState) =
|
||||
let tos = pop_any(state)
|
||||
case tos.kind:
|
||||
of joyTrue, joyFalse:
|
||||
state.stack = tos ^^ state.stack
|
||||
of joyInt:
|
||||
push_bool(tos.intVal != zero, state)
|
||||
of joyList:
|
||||
push_bool(not tos.listVal.isEmpty, state)
|
||||
else:
|
||||
raise newException(ValueError, "Cannot Boolify.")
|
||||
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
#[
|
||||
|
||||
Copyright © 2021 Simon Forman
|
||||
|
||||
This file is part of Bliss
|
||||
|
||||
Bliss is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bliss is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bliss. If not see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
]#
|
||||
import strutils, bigints, fp, types
|
||||
|
||||
proc pr_str(thing: JoyType): string
|
||||
|
||||
proc joystr(s: JoyListType): string =
|
||||
s.map(pr_str).asSeq.join(" ")
|
||||
|
||||
proc pr_str(thing: JoyType): string =
|
||||
case thing.kind
|
||||
of joyAtom: thing.atomVal
|
||||
of joyInt: thing.intVal.toString
|
||||
of joyList: "[" & joystr(thing.listVal) & "]"
|
||||
of joyParseError: thing.errorMessage
|
||||
of joyTrue: "true"
|
||||
of joyFalse: "false"
|
||||
|
||||
proc print_expression*(stack: JoyListType): string =
|
||||
joystr(stack)
|
||||
|
||||
proc print_stack*(stack: JoyListType): string =
|
||||
joystr(stack.reverse)
|
||||
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
#[
|
||||
|
||||
Copyright © 2021 Simon Forman
|
||||
|
||||
This file is part of Bliss
|
||||
|
||||
Bliss is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bliss is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bliss. If not see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
]#
|
||||
import pegs, bigints, fp, types
|
||||
|
||||
type
|
||||
|
||||
Token = string
|
||||
|
||||
Reader = tuple
|
||||
tokens : seq[Token]
|
||||
position: int
|
||||
eof: bool
|
||||
|
||||
let token_pattern = peg"""
|
||||
|
||||
Token <- Bracket / Symbol
|
||||
|
||||
Bracket <- '[' / ']'
|
||||
Symbol <- (!Bracket \S)+
|
||||
|
||||
"""
|
||||
|
||||
# TODO: Maybe use PEG eventParser?
|
||||
|
||||
|
||||
proc peek(reader: Reader): Token =
|
||||
reader.tokens[reader.position]
|
||||
|
||||
|
||||
proc next(reader: var Reader): Token =
|
||||
if reader.eof:
|
||||
raise newException(ValueError, "EOF")
|
||||
result = peek(reader)
|
||||
inc reader.position
|
||||
reader.eof = reader.position >= reader.tokens.len
|
||||
|
||||
|
||||
proc read_atom(reader: var Reader): JoyType =
|
||||
let tok = next(reader)
|
||||
if tok =~ peg"^('+' / '-' )? \d+$":
|
||||
JoyType(kind: joyInt, intVal: tok.initBigInt)
|
||||
elif tok == "true": j_true
|
||||
elif tok == "false": j_false
|
||||
else: JoyType(kind: joyAtom, atomVal: tok)
|
||||
|
||||
|
||||
proc read_form(reader: var Reader): JoyType
|
||||
|
||||
|
||||
proc read_list(reader: var Reader): JoyType =
|
||||
var items : seq[JoyType] = @[]
|
||||
discard next(reader) # Skip the '['.
|
||||
while true:
|
||||
if reader.eof:
|
||||
return JoyType(kind: joyParseError, errorMessage: "EOF while scanning list.")
|
||||
if peek(reader) == "]":
|
||||
discard next(reader) # Skip the ']'.
|
||||
break
|
||||
items.add(read_form(reader))
|
||||
JoyType(kind: joyList, listVal: items.asList)
|
||||
|
||||
|
||||
proc read_form(reader: var Reader): JoyType =
|
||||
if reader.eof:
|
||||
# Blank or empty input, not really an error.
|
||||
JoyType(kind: joyParseError, errorMessage: "")
|
||||
elif peek(reader) == "[":
|
||||
read_list(reader)
|
||||
else:
|
||||
read_atom(reader)
|
||||
|
||||
|
||||
proc tokens_to_reader(tokens: seq[Token]): Reader =
|
||||
var reader: Reader = (
|
||||
tokens: tokens,
|
||||
position: 0,
|
||||
eof: tokens.len == 0
|
||||
)
|
||||
reader
|
||||
|
||||
|
||||
proc read_str*(str: string): JoyListType =
|
||||
var items : seq[JoyType] = @[]
|
||||
var reader = tokens_to_reader(findAll(str, token_pattern))
|
||||
while not reader.eof:
|
||||
items.add(read_form(reader))
|
||||
items.asList
|
||||
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
#[
|
||||
|
||||
Copyright © 2021 Simon Forman
|
||||
|
||||
This file is part of Bliss
|
||||
|
||||
Bliss is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bliss is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bliss. If not see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
]#
|
||||
import bigints, fp
|
||||
|
||||
type
|
||||
|
||||
JoyListType* = List[JoyType]
|
||||
JoyMapType* = Map[string, JoyListType]
|
||||
|
||||
JoyState* = tuple
|
||||
stack: JoyListType
|
||||
expression: JoyListType
|
||||
|
||||
JoyTypeType* = enum
|
||||
joyAtom,
|
||||
joyFalse,
|
||||
joyInt,
|
||||
joyList,
|
||||
joyParseError,
|
||||
joyTrue
|
||||
|
||||
JoyType* = ref object
|
||||
case kind*: JoyTypeType
|
||||
of joyAtom: atomVal*: string
|
||||
of joyFalse, joyTrue: nil
|
||||
of joyInt: intVal*: BigInt
|
||||
of joyList: listVal*: JoyListType
|
||||
of joyParseError: errorMessage*: string
|
||||
|
||||
|
||||
# Singleton values for Boolean type.
|
||||
|
||||
let j_true* = JoyType(kind: joyTrue)
|
||||
let j_false* = JoyType(kind: joyFalse)
|
||||
|
||||
# Singleton values for Symbols.
|
||||
|
||||
let j_loop* = JoyType(kind: joyAtom, atomVal: "loop")
|
||||
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
#[
|
||||
|
||||
Copyright © 2021 Simon Forman
|
||||
|
||||
This file is part of Bliss
|
||||
|
||||
Bliss is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bliss is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bliss. If not see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
]#
|
||||
import bigints, fp, types
|
||||
|
||||
|
||||
proc pop_any*(state: var JoyState): JoyType =
|
||||
# TODO: detect and report nils.
|
||||
if state.stack.isEmpty:
|
||||
raise newException(ValueError, "Not enough values on stack.")
|
||||
let a = state.stack.head
|
||||
state.stack = state.stack.tail
|
||||
return a
|
||||
|
||||
proc pop_bool*(state: var JoyState): bool =
|
||||
let a = pop_any(state)
|
||||
case a.kind:
|
||||
of joyTrue: result = true
|
||||
of joyFalse: result = false
|
||||
else:
|
||||
raise newException(ValueError, "Not a Boolean value.")
|
||||
|
||||
proc pop_int*(state: var JoyState): BigInt =
|
||||
let a = pop_any(state)
|
||||
case a.kind:
|
||||
of joyInt:
|
||||
return a.intVal
|
||||
else:
|
||||
raise newException(ValueError, "Not an integer.")
|
||||
|
||||
proc pop_list*(state: var JoyState): JoyListType =
|
||||
let a = pop_any(state)
|
||||
case a.kind:
|
||||
of joyList:
|
||||
return a.listVal
|
||||
else:
|
||||
raise newException(ValueError, "Not a list.")
|
||||
|
||||
|
||||
proc push_int*(a: BigInt, state: var JoyState) =
|
||||
state.stack = JoyType(kind: joyInt, intVal: a) ^^ state.stack
|
||||
|
||||
proc push_list*(a: JoyListType, state: var JoyState) =
|
||||
state.stack = JoyType(kind: joyList, listVal: a) ^^ state.stack
|
||||
|
||||
proc push_bool*(a: bool, state: var JoyState) =
|
||||
if a:
|
||||
state.stack = j_true ^^ state.stack
|
||||
else:
|
||||
state.stack = j_false ^^ state.stack
|
||||
|
||||
Loading…
Reference in New Issue