uhmanoa-transpiler-project / shaka-scheme Goto Github PK
View Code? Open in Web Editor NEWThe official repository for the UH Manoa Transpiler Project's Scheme interpreter, Shaka Scheme.
The official repository for the UH Manoa Transpiler Project's Scheme interpreter, Shaka Scheme.
This is necessary.
If you give 1/2
to the parse
function, it does not correctly push the correct list form onto the list -- it pushes only 1
, or the numerator part.
We need to expand the parser for numbers so that it correctly peeks ahead and does the full parse for the number form.
The evaluation model for Shaka Scheme is changing to match the heap-based evaluation model as outlined by Dybvig in Three Implementation Models for Scheme. I will go through the codebase and salvage the parts that can remain intact.
The EvaluationStrategy for Define
is unfinished.
It evaluates a list of the form:
<Symbol> <Expression>
using eval::Expression
in the process with another Evaluator
object.
Then, it binds the symbol in the local environment to the result of evaluating the expression.
I am trying to get all of the numeric predicates integrated into our REPL program. When I attempt to evaluate:
>>> (< 4 5)
at the REPL I get the following parser error
Parser.parse_token: invalid token
libc++abi: terminating input with uncaught exception of type char const*
Upon inspection of the Tokenizer.h file, I found a function with the following signature:
bool is_special_initial (char c)
In the body of this function, we check if the character is equal to a number of characters. I discovered that we were checking if c == '>'
twice. I changed one of these to be c == '<'
hoping that would fix the issue. Unfortunately, this did not fix the parser error. I am going to try and investigate further to see if I can find source of the issue. As I am mostly unfamiliar with the structure of the parser code, any assistance that I could get in this matter would be much appreciated.
In R7RS scheme, it should be possible to define a lambda procedure of the form:
(lambda x x)
Which will collect any number of arguments into a list and bind the variable x to this list. However, attempts to define and call such a lambda procedure in our REPL program results in the following error message:
Error: DataNode.length: argument is not a list
I will begin exhaustive unit testing to determine the source of this issue and hopefully correct it.
One of the problem with DataNode
in core/base/DataNode.h
is that its single-Data
construct will automatically place the head
into the DataNode's head
space without checking what exactly it is.
This means that it is valid to do this:
make_node(make_node(make_node(Number(1))))
But, when you print it out, it will print out nothing, because the operator<<
relies on the assumptions made by the predicates like is_pair()
. This means that it is completely missed by the logic when printing it out.
Funny thing enough, it will not be detected by a pair, because it is, indeed, considered as a single-value DataNode
but it may hold a list as its single value. It's confusing.
I tried to change the constructor so that it will only construct with NodePtr
that are of the value nullptr
for single values, but this causes test cases to fail. More research needs to be done into this, as this implies that this is being done somewhere, but I myself do not know where.
Another way is to dynamically detect and fix any "nesting," similar to how some monads fold two M(M(value))
into one M(value)
. This is run-time performance cost, however, and therefore, is not the favorable solution (although the detection part may help us understand when such a thing is being used).
Throughout the course of the project, we have had difficulty building for the project with clang++
. Instead, we have opted for the c++
compiler alias that is available on most major platforms, and appears to be usually an alias for either g++
or clang++
.
Note that linking in Google Test is often different when compiling with clang++
on Mac OS X due to a different linking scheme that differs from the project's preferred g++
settings.
In the future, we may adopt CMake support in order to get more acceptable cross-platform availability. But we are currently comfortable with using a simple GNU Make-based build system.
I attempted to define the following simple lambda procedure in our REPL today:
(define add (lambda (x y) (+ x y)))
The procedure is seemingly successfully parsed in, however when I attempt to call the procedure as follows:
(add 1 2)
I get back the following error:
Error: eval.Variable: variable y is undefined
Not sure what specifically is causing this issue, but it seems as thought the last parameter in the parameter list is not being properly bound to its argument at call time. Notably, the following extended definition:
(define add3 (lambda (x y z) (+ x y z)))
With call:
(add3 1 2 3)
Errors similarly with:
Error: eval.Variable: variable z is undefined
The last parameter is not being bound to its argument successfully. I will attempt to resolve this issue over the week-end when I have time, but thought I would point it out to everyone, because it should be somewhat trivial to resolve.
-Troy
String constructor for specified length of string is inappropriately created causing the size of the string to be incorrect. At the same time, the comparison operators were not supposed to compare length but whether they are (non-)monotonically decreasing/increasing.
The GCNode Assignment operator is missing the return *this
return statement, leading to undefined behavior.
If
Define
Quote
Proc Call
Expression
Proccall is not written to accommodate NativeProcedure and the newly created PrimitiveProcedure and needs to be augmented to accommodate these types of Procedures. There is also a bug in the evaluation mechanism that seems to be rooted in Proccall_impl. A call to eval::Expression() on (define a 1) returns a DataNode.cdr runtime error on something that is not a pair.
We will want to focus on externalizing the project at some point. Somebody will need to write a piece in order to guide people towards development.
Redo test cases for Std Proc Boolean.
If requires Eval_Expression which isn't currently done.
We just use the sqrt(double)
implementation from C which gives undefined behavior for the ACTUAL return result, except raising a domain error.
Our sister project, Shaka Show, will be needing a low-level C++ API to support their functionality.
This will involve extending the HeapVirtualMachine
and perhaps even the Compiler
to prevent stripping of syntax information and propagate it down the evaluation pipeline until it reaches the virtual machine. Then, the current C++ API (also a work in progress) will be joined by another API to the entire pipeline in order to expose information like:
x
refer to now?One idea for doing this is implementing syntax objects, an approach taken by academic researchers in literature as well as Racket's current implementation as of the time of writing. This will also simultaneously make syntax-rules
macros achievable (syntax-case
macros are out of the question since they allow for too much computation at compile-time -- in fact, they trigger the need to support an arbitrary amount of levels of compile-time/run-time layers or steps in order to support modules. For more info, look at Chez Scheme's or Racket's concept of "phases"). I plan to achieve this by implementing a monad wrapper to go around our current Data
class in order to preserve all of our other functions that go from Data -> Data
in a clean, functional manner.
@paulolemus and I will be taking ownership for this part.
This is relatively new, untested, not sure if working yet
test case 2 in src/eval/test-Define.cpp
trying to do:
(define a (lambda (x) x))
I cannot implement syntax-case
. But I can do syntax-rules
macros!
We are currently using a makeshift build system purely off of Make. This is bad, and is quite clunky, especially since we've encountered portability problems.
Moving to CMake will have many benefits, including increasing cross-platform compatibility and also paving the way for tighter integration with CLion.
Still need to get PrimitiveProcedure class working
Here is a log of input to the current commit of Shaka Scheme (7b67f42)'s REPL of main.cpp
.
$ ./shaka-scheme-repl-0.1.exe
Welcome to Shaka Scheme!
> (define a (lambda (x) x))
#<procedure>
> a
#<procedure>
> (a 1)
1
> #(a)
#(0x4aedea0)
> #('a b c)
#((quote a) b 0x4bc76c0)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.