├── .gitignore ├── .gitmodules ├── COPYING ├── README.mkd ├── THANKS.mkd ├── TODO.mkd ├── doc ├── LanguageDesign.md └── Syntax.md ├── logo.png ├── logo_maki.jpg └── src ├── CL-Backend ├── Makefile ├── README.mkd ├── TODO ├── loli-assert.lisp ├── loli-base.lisp ├── loli-env.lisp ├── loli-error.lisp ├── loli-init.lisp ├── loli-lambda.lisp ├── loli-main.lisp ├── loli-make.lisp ├── loli-obj.lisp ├── loli-prim.lisp ├── loli-read.lisp ├── loli-repl.lisp ├── loli-test.lisp ├── loli-testcases.lisp ├── loli-typeclass.lisp └── package.lisp ├── Erl-Backend ├── README.mkd ├── loli_repl.erl └── loli_typeclass.erl ├── LoLi ├── README.mkd ├── currentc ├── currentg ├── functions.loli ├── header │ ├── loli.h │ ├── loli_apply.h │ ├── loli_ast.h │ ├── loli_cbmi.h │ ├── loli_cond.h │ ├── loli_cons.h │ ├── loli_def.h │ ├── loli_env.h │ ├── loli_eval.h │ ├── loli_file.h │ ├── loli_gc.h │ ├── loli_gui.h │ ├── loli_lambda.h │ ├── loli_let.h │ ├── loli_list.h │ ├── loli_output.h │ ├── loli_parser.h │ ├── loli_prim.h │ ├── loli_read.h │ ├── loli_repl.h │ ├── loli_set.h │ ├── loli_stack.h │ ├── loli_symbols.h │ └── loli_types.h ├── loli_apply.cpp ├── loli_ast.cpp ├── loli_cbmi.cpp ├── loli_cli.cpp ├── loli_cond.cpp ├── loli_cons.cpp ├── loli_def.cpp ├── loli_env.cpp ├── loli_eval.cpp ├── loli_file.cpp ├── loli_gui.cpp ├── loli_gui.glade ├── loli_lambda.cpp ├── loli_let.cpp ├── loli_list.cpp ├── loli_main.cpp ├── loli_output.cpp ├── loli_parser.cpp ├── loli_prim.cpp ├── loli_read.cpp ├── loli_repl.cpp ├── loli_set.cpp ├── loli_stack.cpp ├── loli_symbols.cpp └── loli_types.cpp ├── LoLi2 ├── .sln ├── .ycm_extra_conf.py ├── .ycm_extra_conf.pyc ├── Makefile ├── README.mkd ├── currentc ├── include │ ├── loli_apply.h │ ├── loli_env.h │ ├── loli_eval.h │ ├── loli_lambda.h │ ├── loli_obj.h │ ├── loli_parser.h │ ├── loli_prim.h │ ├── loli_reader.h │ ├── loli_repl.h │ ├── loli_stack.h │ ├── loli_type.h │ ├── loli_typeclass.h │ ├── loli_typeenv.h │ └── loli_util.h ├── loli2test.cpp ├── loli_apply.cpp ├── loli_cbmi.cpp ├── loli_env.cpp ├── loli_eval.cpp ├── loli_lambda.cpp ├── loli_main.cpp ├── loli_obj.cpp ├── loli_parser.cpp ├── loli_prim.cpp ├── loli_reader.cpp ├── loli_repl.cpp ├── loli_stack.cpp ├── loli_type.cpp ├── loli_typeclass.cpp ├── loli_typeenv.cpp ├── loli_util.cpp └── test ├── PHP-Backend └── README.mkd ├── Parser ├── README.md ├── Tokenizer.cpp ├── Tokenizer.h └── tests │ └── test_tokenizer.cpp └── README.mkd /.gitignore: -------------------------------------------------------------------------------- 1 | ### C++ ### 2 | # Compiled Object files 3 | *.slo 4 | *.lo 5 | *.o 6 | *.obj 7 | 8 | # Precompiled Headers 9 | *.gch 10 | *.pch 11 | 12 | # Compiled Dynamic libraries 13 | *.so 14 | *.dylib 15 | *.dll 16 | 17 | # Fortran module files 18 | *.mod 19 | 20 | # Compiled Static libraries 21 | *.lai 22 | *.la 23 | *.a 24 | *.lib 25 | 26 | # Executables 27 | *.exe 28 | *.out 29 | *.app 30 | 31 | 32 | ### C ### 33 | # Object files 34 | *.o 35 | *.ko 36 | *.obj 37 | *.elf 38 | 39 | # Precompiled Headers 40 | *.gch 41 | *.pch 42 | 43 | # Libraries 44 | *.lib 45 | *.a 46 | *.la 47 | *.lo 48 | 49 | # Shared objects (inc. Windows DLLs) 50 | *.dll 51 | *.so 52 | *.so.* 53 | *.dylib 54 | 55 | # Executables 56 | *.exe 57 | *.out 58 | *.app 59 | *.i*86 60 | *.x86_64 61 | *.hex 62 | 63 | 64 | ### CMake ### 65 | CMakeCache.txt 66 | CMakeFiles 67 | Makefile 68 | cmake_install.cmake 69 | install_manifest.txt 70 | 71 | 72 | ### Emacs ### 73 | # -*- mode: gitignore; -*- 74 | *~ 75 | \#*\# 76 | /.emacs.desktop 77 | /.emacs.desktop.lock 78 | *.elc 79 | auto-save-list 80 | tramp 81 | .\#* 82 | 83 | # Org-mode 84 | .org-id-locations 85 | *_archive 86 | 87 | # flymake-mode 88 | *_flymake.* 89 | 90 | # eshell files 91 | /eshell/history 92 | /eshell/lastdir 93 | 94 | # elpa packages 95 | /elpa/ 96 | 97 | # reftex files 98 | *.rel 99 | 100 | # AUCTeX auto folder 101 | /auto/ 102 | 103 | # cask packages 104 | .cask/ 105 | 106 | # erlang 107 | *.beam 108 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/gc"] 2 | path = src/gc 3 | url = https://github.com/Z-Shang/bdwgc 4 | -------------------------------------------------------------------------------- /README.mkd: -------------------------------------------------------------------------------- 1 | LoLi 2 | ==== 3 | [![GPL Licence](https://badges.frapsoft.com/os/gpl/gpl.svg?v=103)](https://opensource.org/licenses/GPL-3.0/) 4 | 5 | LoLi is another approach to System F-sub in a **LISPy** way. 6 | 7 | The C++ version is paused, I'm doing the Common Lisp version now. 8 | 9 | ![LoLi LOGO, with authorization from illustrator](/logo.png) 10 | 11 | Why LoLi 12 | -------- 13 | 14 | I'm a LOLICON! LOLI is the JUSTICE! 15 | 16 | What is LoLi 17 | ------------ 18 | 19 | I intended to implement a Lisp dialect that combines the features of both ***Lisp - 1*** and ***Lisp - 2*** that means, LoLi will have one name space like in **Scheme** but data with the same names can exist at the same time like in **Common Lisp** and the interpreter will choose which one to eval according to the context, for example: 20 | 21 | ```Lisp 22 | (get-func 'foo) 23 | ;=> # ;;(def foo (\ (x) (+ x 1))) 24 | 25 | (get-sym 'foo) 26 | ;=> '(foo . 1) 27 | 28 | (foo foo) 29 | ;=> 2 30 | ``` 31 | 32 | and other features like the interpreter itself can eval an expression without getting into the REPL: 33 | 34 | ```Shell 35 | ./loli --eval “(+ 1 2)” 36 | # out: 3 37 | ``` 38 | 39 | and even more complicated: 40 | 41 | ```Shell 42 | ./loli --eval “(def foo (x) (.\ (y) (+ y x))) (def bar (foo 2)) (bar 3)” 43 | # out: 5 44 | ``` 45 | 46 | JOIN US (ME) PLEASE 47 | ------------------- 48 | 49 | If you are not satisfied with current Lisp dialects, or if you have some great ideas want to make them into a programming language, then just fork and send me a pull request, any help is appreciated. 50 | 51 | Reason Why The Developing Speed is So Slow 52 | ------------------------------------------ 53 | 54 | Go to the Google Play Store / Apple App Store and search for a game called : "Love Live", play it, you will know. 55 | 56 | Also, since C++ is way too complex, if you are an expert dealing with C++ template programming / meta programming, please join my work. Otherwise I will rewrite it in Common Lisp. 57 | -------------------------------------------------------------------------------- /THANKS.mkd: -------------------------------------------------------------------------------- 1 | With great thanks to : 2 | = 3 | **Andru Luvisi** (Author of SL3.C) 4 | 5 | **Anthony C. Hay** (Author of the Lisp interpreter in 90 lines C++) 6 | 7 | **Boehm GC** 8 | 9 | **c2.com** (For their "Implementing Lisp" page) 10 | 11 | **Peter Norvig** (Author of the Lis.py) 12 | 13 | --- 14 | 15 | Special Thanks To: 16 | = 17 | **Fiddle Heads** (For their great coffee and high quality working environment) 18 | 19 | --- 20 | 21 | *In alphabetical order* 22 | -------------------------------------------------------------------------------- /TODO.mkd: -------------------------------------------------------------------------------- 1 | 1. Implement the LoLi Compiler (Aka LLVM frontend) 2 | 3 | 2. Implement the LoLi type system (Typeclass) 4 | 5 | >Done. 6 | 7 | 3. Start to build the new Read-Parse module 8 | 9 | >Done. 10 | 11 | 4. Improve the EVAL module (With the context based meaning inferring system) 12 | 13 | >Done. 14 | 15 | 5. Implement the context based meaning inferring system 16 | 17 | 6. Implement read from file 18 | 19 | >Done. 20 | 21 | 7. Build the CLI userinterface using NCurses 22 | 23 | 8. Finish the core LoLi functions in LoLi 24 | 25 | 9. VIM Plugin 26 | 27 | 10. Cheer 28 | -------------------------------------------------------------------------------- /doc/LanguageDesign.md: -------------------------------------------------------------------------------- 1 | Language Design of LoLi1 2 | ======================== 3 | 4 | Z.Shang 5 | 2014 6 | 7 | THIS ONE IS OUTDATED, DETAILS MAY BE DIFFERENT FROM THE IMPLEMENTATION 8 | 9 | LoLi is a Lisp dialect that combines Lisp - 1 and Lisp - 2, that means in LoLi 10 | there will be one namespace but supporting duplicated name, and the interpreter 11 | will infer the value based on the comtext (or by manully specified). 12 | 13 | Here is the language design of LoLi: 14 | 15 | Basic Symbols 16 | ------------- 17 | 18 | | Symbol | Description | 19 | |--------------|-----------------------------------------------------| 20 | |`T` | same as `T` in Common Lisp, but not Boolean true. | 21 | |`NIL` | same as `NIL` in Common Lisp, but not Boolean false.| 22 | |`set!` | same as `SET!` in Scheme | 23 | |`def` | like `define` in Scheme or `defvar` in Common Lisp, or `def` in Arc (`(defvar foo #'(lambda ...)` when defining a lambda expression)| 24 | |`\` | `lambda (\ :TYPE-ID (arg-lst) (exp))` | 25 | |`let` | same as `LET` in Common Lisp | 26 | |`quote("\'")` | same as `QUOTE` in Common Lisp/Scheme | 27 | 28 | Naming Regulation 29 | ----------------- 30 | 31 | | What | How | 32 | |------------------|-------------------------------------------------| 33 | |Predicate | end with `?` (E.g. `null?`) | 34 | |Destructive | end with `!` (E.g. `set!`) | 35 | |Recursive Function| end with `-r` (E.g. `map-r`) | 36 | |Global Variable | surround by `**` (E.g. `*TOP-LEVEL*`) | 37 | |Function | use hyphen-connected full spelling (E.g. `number-of-count` but not `numOfCount`)| 38 | |Argument | use "lst" for list, "num" for number, "sym" for symbol| 39 | |Commentary | add comments to the function's parameter and returning type (E.g. ;;Num -> Num)| 40 | 41 | Core Data Structure 42 | ------------------- 43 | 44 | LoLi Objects as defined in `loli_types.h` (the list structured memory): 45 | 46 | ```C++ 47 | struct loliObj { 48 | loliType type; /// enum of types 49 | string value; 50 | loliObj *head; /// Pointer to head(loliObj) 51 | loliObj *tail; /// Pointer to tail(loliObj) 52 | loliObj *env; /// Pointer to environment 53 | procedure *proc; /// Pointer to procedure 54 | // ... 55 | }; 56 | ``` 57 | 58 | Environment 59 | ----------- 60 | 61 | The environment itself is a LoliObj: 62 | 63 | ```Lisp 64 | ([syma . a] ([symb . b] ([symc . c] ( ... ([symn . n] . nil))))) 65 | ; using [] and () just to be clear for reader, in LoLi there will only be ( and ) 66 | ``` 67 | 68 | - Lookup: 69 | Will return a list that contains all the symbols that matches the criteria 70 | - Insert: 71 | Insert the new item while adding to environment to make the environment in 72 | accending order, that makes environment easier to be looked up 73 | 74 | A procedure in LoLi_ENV: 75 | 76 | +-----------------------------------------------+ 77 | | Env Entry | 78 | +-----------------------------------------------+ 79 | | +----------------------------------------+ | 80 | | | cons | | 81 | | +----------------------------------------+ | 82 | | | Symbol (Identifier) | | 83 | | | +------------------------------+ | | 84 | | | | cons | | | 85 | | | +------------------------------+ | | 86 | | | | loliType (Input type) | | | 87 | | | | loliObj proc (Procedure) | | | 88 | | | +------------------------------+ | | 89 | | +----------------------------------------+ | 90 | +-----------------------------------------------+ 91 | 92 | ### Context Based Meaning Inference (CBMI) 93 | 94 | Parse the input into AST, then lookup the corresponding obj in the environment. 95 | 96 | Key concepts for the CBMI: 97 | - Verb : Objects that takes other Objects, for example: Function (`PROC`) and 98 | Lambda (`LAMBDA`) 99 | - Noun : Objects that only have value, for example: Symbol (`SYM`), Number 100 | (`INT` / `FLT`), etc. 101 | -------------------------------------------------------------------------------- /doc/Syntax.md: -------------------------------------------------------------------------------- 1 | Syntax 2 | ====== 3 | 4 | There are two basic elements in LoLi: Atom and List, where Atom can be an 5 | element that is of any non-List types (nor sub-types of List). This is 6 | similar to other LISP dialects. 7 | 8 | A legal expression in LoLi can contain: 9 | 10 | 1. a single Atom, e.g.: `1`, `"String"`, `:NUM`, `Symbol`, `nil` 11 | 2. a List (Including empty list `'()`), e.g.: `(+ 1 2)`, `(def var 123)`, 12 | `(:a 1 :b 2 :c 3)` 13 | - for a List to be evaluated, it must be in a form as a tree that only 14 | the children nodes are nouns, e.g.: (V (V (V N) N) N N N (V N)) 15 | - where verbs are Function type (and its sub-types, like Lambda and 16 | Procedure) 17 | 3. either form 1 or form 2 with a quote `'`, a quotaion is considered 18 | as a List, `(quote foo)` equals to `'foo` 19 | 4. special operator followed by specific element, that are not 20 | implemented / planned yet 21 | 22 | To support the Context-based inferrence, there are some special design 23 | of the Lambda expression in LoLi, inspired by the System-F. 24 | 25 | In LoLi, a type id inside a Lambda expression is required, so it looks like 26 | `(\\ :type (x) (exp))` (equivalent to `.\xTtype` in Systen F). Therefore a 27 | legal Lambda expression in LoLi can look like `(\\ :int (x (y :int)) (+ x y))`, 28 | where `x` can be an element of any type and `y` must be an element of type INT 29 | (and its sub-types). 30 | 31 | To make a generic return in Lambda expression, you can simply use `:OBJ` for 32 | the type of that Lambda expression, since `:OBJ` is the base type of all types 33 | in LoLi. 34 | 35 | The namespace (environment) of the Inferrence system can contain a multiple 36 | bind of one symbol to make LoLi more similar to human language, you can leave 37 | the type inferrence to the interpreter (e.g. 38 | `[ (a . 1) (a . "String") (a . #INT>) ]` is a legal environment). 39 | If you want to specify a type, you can use `get-type` followed by a symbol 40 | and a type id, e.g.: `(get-type a :int)` 41 | 42 | For the environment above, you can use the Lambda expression `a` in either way: 43 | `(a a)`, `(a (get-type a :int))` 44 | 45 | Function `def` binds a symbol to an element, `(def a 1)`, `(def a "String)`, 46 | `(def a (\\ ... ))` 47 | 48 | Function `set!` will change the value bind to a symbol, `(set! a 2)` will make 49 | the bind (a . 1) into (a . 2), `(set! (get-type a :flt) 2)` will change the 50 | float number bind to a into 2 (the bind must exists first, otherwise you 51 | should use `def` to create a new bind) 52 | 53 | There is no `&body` or `&rest` features in LoLi and the argument list must have 54 | a certain arity. If you really want to use a vaiable argument list, put them 55 | into a List: `(\\ :type (a b c (rest :LIST)) exp)` 56 | 57 | Misc 58 | ---- 59 | 60 | The BOOLEAN type in LoLi is a sub-type of KEYWORD, so they look like: `:true`, 61 | `:false` instead of the Scheme style `#true`, `#false`. 62 | 63 | There also exist `T` and `NIL`, they are SYMBOLs, and DO NOT have BOOLEAN value, 64 | `NIL` equals to `'()`. 65 | 66 | The type ids are also KEYWORDs. 67 | 68 | You can extend types by creating sub-types (which is not implemented yet) 69 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LoLi-Lang/LoLi/9306a531a42df9e81b75de4bc278aa8dc9c22a3f/logo.png -------------------------------------------------------------------------------- /logo_maki.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LoLi-Lang/LoLi/9306a531a42df9e81b75de4bc278aa8dc9c22a3f/logo_maki.jpg -------------------------------------------------------------------------------- /src/CL-Backend/Makefile: -------------------------------------------------------------------------------- 1 | LISP = sbcl 2 | 3 | main: 4 | $(LISP) --load loli-make.lisp 5 | -------------------------------------------------------------------------------- /src/CL-Backend/README.mkd: -------------------------------------------------------------------------------- 1 | LoLi CL-Backend 2 | =============== 3 | 4 | This is the Common Lisp Backend to make the development faster, the C++ version is still going on. 5 | -------------------------------------------------------------------------------- /src/CL-Backend/TODO: -------------------------------------------------------------------------------- 1 | Features to be done: 2 | 3 | `assert` 4 | to assert a type of a symbol in a temporary environment, use it like `let`: 5 | 6 | assert LIST EXP 7 | 8 | LOLI-LIST, LOLI-OBJ => LOLI-OBJ 9 | 10 | (assert ((SYM1 :TYPE-ID) 11 | (SYM2 :TYPE-ID) 12 | ...) 13 | EXP) 14 | 15 | Redo the eval order, make it lazy-like 16 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-assert.lisp: -------------------------------------------------------------------------------- 1 | (require 'loli-package "package") 2 | (require 'loli-obj "loli-obj") 3 | (require 'loli-type-class "loli-typeclass") 4 | (require 'loli-prim "loli-prim") 5 | (require 'loli-env "loli-env") 6 | 7 | (in-package #:loli) 8 | 9 | (defun type-id-list-to-typed-list (lst &optional (env *TOP-ENV*)) 10 | (if (equalp (loli-head lst) loli-nil) 11 | loli-nil 12 | (loli-cons 13 | (loli-cons 14 | (loli-head (loli-head lst)) 15 | (typed-lookup (loli-head (loli-head lst)) 16 | (type-id-to-type (loli-head (loli-tail (loli-head lst)))) 17 | env)) 18 | (type-id-list-to-typed-list (loli-tail lst) env)))) 19 | 20 | (defun loli-assert 21 | (lst exp) 22 | 23 | 24 | ) 25 | 26 | (provide 'loli-assert) 27 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-base.lisp: -------------------------------------------------------------------------------- 1 | (require 'loli-package "package") 2 | (require 'loli-type-class "loli-typeclass") 3 | 4 | (in-package :loli) 5 | 6 | 7 | (provide 'loli-base) 8 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-env.lisp: -------------------------------------------------------------------------------- 1 | (require 'loli-package "package") 2 | (require 'loli-obj "loli-obj") 3 | (require 'loli-prim "loli-prim") 4 | (require 'loli-lambda "loli-lambda") 5 | (require 'loli-type-class "loli-typeclass") 6 | 7 | (in-package #:loli) 8 | 9 | (defvar *TOP-ENV* loli-nil "The TOP-LEVEL Environment of LoLi") 10 | 11 | (defun loli-lookup (sym &optional (env *TOP-ENV*)) 12 | (if (sub-type-p (loli-obj-loli-type env) *type-cons*) 13 | (if (equalp (loli-obj-value sym) 14 | (loli-obj-value (loli-head (loli-head env)))) 15 | (loli-cons (loli-tail (loli-head env)) 16 | (loli-lookup sym 17 | (loli-tail env))) 18 | (loli-lookup sym 19 | (loli-tail env))) 20 | loli-nil)) 21 | 22 | (defun get-typed (type loli-c) 23 | (if (equal (loli-obj-loli-type loli-c) *type-cons*) 24 | (if (sub-type-p (loli-obj-loli-type 25 | (loli-head loli-c)) 26 | type) 27 | (loli-head loli-c) 28 | (get-typed type (loli-tail loli-c))) 29 | 'NO-MATCHING-FOUND)) 30 | 31 | (defun typed-lookup (sym &optional (type *type-obj*) (env *TOP-ENV*)) 32 | (get-typed type 33 | (loli-lookup sym env))) 34 | 35 | ;;INIT TOP ENV 36 | (setf *TOP-ENV* 37 | (loli-cons 38 | (loli-cons (to-loli-sym 'nil) 39 | loli-nil) 40 | *TOP-ENV*)) 41 | 42 | (setf *TOP-ENV* 43 | (loli-cons 44 | (loli-cons (to-loli-sym 't) 45 | loli-t) 46 | *TOP-ENV*)) 47 | 48 | (setf *TOP-ENV* 49 | (loli-cons 50 | (loli-cons (to-loli-sym 'aa) 51 | (to-loli-int 123)) 52 | *TOP-ENV*)) 53 | 54 | (setf *TOP-ENV* 55 | (loli-cons 56 | (loli-cons (to-loli-sym '+) 57 | loli-add-f) 58 | *TOP-ENV*)) 59 | 60 | (setf *TOP-ENV* 61 | (loli-cons 62 | (loli-cons (to-loli-sym '-) 63 | loli-sub-f) 64 | *TOP-ENV*)) 65 | 66 | (setf *TOP-ENV* 67 | (loli-cons 68 | (loli-cons (to-loli-sym '*) 69 | loli-mul-f) 70 | *TOP-ENV*)) 71 | 72 | (setf *TOP-ENV* 73 | (loli-cons 74 | (loli-cons (to-loli-sym '/) 75 | loli-div-f) 76 | *TOP-ENV*)) 77 | 78 | (setf *TOP-ENV* 79 | (loli-cons 80 | (loli-cons (to-loli-sym '=) 81 | loli-num-eq-f) 82 | *TOP-ENV*)) 83 | 84 | (setf *TOP-ENV* 85 | (loli-cons 86 | (loli-cons (to-loli-sym 'quit) 87 | loli-quit-f) 88 | *TOP-ENV*)) 89 | 90 | (setf *TOP-ENV* 91 | (loli-cons 92 | (loli-cons (to-loli-sym 'exit) 93 | loli-quit-f) 94 | *TOP-ENV*)) 95 | 96 | (setf *TOP-ENV* 97 | (loli-cons 98 | (loli-cons (to-loli-sym 'cons) 99 | loli-cons-f) 100 | *TOP-ENV*)) 101 | 102 | (setf *TOP-ENV* 103 | (loli-cons 104 | (loli-cons (to-loli-sym 'head) 105 | loli-head-f) 106 | *TOP-ENV*)) 107 | 108 | (setf *TOP-ENV* 109 | (loli-cons 110 | (loli-cons (to-loli-sym 'tail) 111 | loli-tail-f) 112 | *TOP-ENV*)) 113 | 114 | (setf *TOP-ENV* 115 | (loli-cons 116 | (loli-cons (to-loli-sym '\\) 117 | loli-lambda-f) 118 | *TOP-ENV*)) 119 | 120 | (setf *TOP-ENV* 121 | (loli-cons 122 | (loli-cons (to-loli-sym '>) 123 | loli-num-greater-f) 124 | *TOP-ENV*)) 125 | 126 | (setf *TOP-ENV* 127 | (loli-cons 128 | (loli-cons (to-loli-sym '<) 129 | loli-num-less-f) 130 | *TOP-ENV*)) 131 | 132 | (setf *TOP-ENV* 133 | (loli-cons 134 | (loli-cons (to-loli-sym 'and) 135 | loli-and-f) 136 | *TOP-ENV*)) 137 | 138 | (setf *TOP-ENV* 139 | (loli-cons 140 | (loli-cons (to-loli-sym 'or) 141 | loli-or-f) 142 | *TOP-ENV*)) 143 | 144 | (setf *TOP-ENV* 145 | (loli-cons 146 | (loli-cons (to-loli-sym 'not) 147 | loli-not-f) 148 | *TOP-ENV*)) 149 | 150 | (defun loli-def (name value) 151 | (if (equalp (typed-lookup name (loli-obj-loli-type value)) 152 | 'NO-MATCHING-FOUND) 153 | (setf *TOP-ENV* (loli-cons (loli-cons name value) *TOP-ENV*)) 154 | (format *standard-output* "Symbol bind already exists!~%"))) 155 | 156 | (defconstant loli-def-f 157 | (to-loli-proc 158 | (make-loli-proc-struct :return-type *type-obj* :arg-type *type-obj* 159 | :arity 2 :cl-fn #'loli-def))) 160 | 161 | (setf *TOP-ENV* 162 | (loli-cons 163 | (loli-cons (to-loli-sym 'def) 164 | loli-def-f) 165 | *TOP-ENV*)) 166 | 167 | (defun loli-set (name value) 168 | (if (equalp (typed-lookup name (loli-obj-loli-type value)) 169 | 'NO-MATCHING-FOUND) 170 | (format *standard-output* 171 | "Error: the symbol ~A is not bound to the type ~A~%" 172 | (loli-obj-value name) 173 | (loli-type-class-id (loli-obj-loli-type value))) 174 | (setf (typed-lookup name (loli-obj-loli-type value)) 175 | value))) 176 | 177 | (defconstant loli-set-f 178 | (to-loli-proc 179 | (make-loli-proc-struct :return-type *type-obj* :arg-type *type-obj* 180 | :arity 2 :cl-fn #'loli-set) 181 | '())) 182 | 183 | (setf *TOP-ENV* 184 | (loli-cons 185 | (loli-cons (to-loli-sym 'set!) 186 | loli-set-f) 187 | *TOP-ENV*)) 188 | 189 | (provide 'loli-env) 190 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-error.lisp: -------------------------------------------------------------------------------- 1 | (require 'loli-package "package") 2 | (require 'loli-obj "loli-obj") 3 | (require 'loli-read "loli-read") 4 | 5 | (in-package #:loli) 6 | 7 | (define-condition loli-error (error) 8 | ()) 9 | 10 | (define-condition loli-err-symbol-not-bound (loli-error) 11 | ((err-obj :initarg :err-obj :reader err-obj) 12 | (err-env :initarg :err-env :reader err-env)) 13 | (:report (lambda (condition stream) 14 | (format stream "Error: Symbol ~A is not bound" 15 | (loli-obj-value (err-obj condition)))))) 16 | 17 | (defun handle-loli-symbol-not-bound (condition) 18 | (when (typep condition 'loli-err-symbol-not-bound) 19 | (loli-symbol-not-bound-debug (err-obj condition)))) 20 | 21 | (provide 'loli-error) 22 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-init.lisp: -------------------------------------------------------------------------------- 1 | (require 'loli-package "package") 2 | (require 'loli-obj "loli-obj") 3 | (require 'loli-prim "loli-prim") 4 | (require 'loli-env "loli-env") 5 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-lambda.lisp: -------------------------------------------------------------------------------- 1 | (require 'loli-package "package") 2 | (require 'loli-obj "loli-obj") 3 | (require 'loli-type-class "loli-typeclass") 4 | (require 'loli-prim "loli-prim") 5 | (require 'loli-base "loli-base") 6 | 7 | (in-package #:loli) 8 | 9 | ;;LoLi's Lambda: 10 | ;; (\\ :RETURN-TYPE (ARG-LST) EXP) 11 | 12 | (defstruct loli-lambda-struct 13 | (return-type *type-obj* :type loli-type-class) 14 | (arg-lst loli-nil :type loli-obj) 15 | (arg-types '() :type list) 16 | (exp loli-nil :type loli-obj)) 17 | 18 | (defun arg-lst-to-sym-lst (arg-lst) 19 | (if (equalp (loli-obj-value arg-lst) 20 | 'nil) 21 | loli-nil 22 | (if (sub-type-p (loli-obj-loli-type (loli-head arg-lst)) 23 | *type-cons*) 24 | (loli-cons (loli-head (loli-head arg-lst)) 25 | (arg-lst-to-sym-lst (loli-tail arg-lst))) 26 | (loli-cons (loli-head arg-lst) 27 | (arg-lst-to-sym-lst (loli-tail arg-lst)))))) 28 | 29 | (defun arg-lst-to-type-lst (arg-lst) 30 | (if (equalp (loli-obj-value arg-lst) 31 | 'nil) 32 | nil 33 | (if (sub-type-p (loli-obj-loli-type (loli-head arg-lst)) 34 | *type-cons*) 35 | (cons (loli-head (loli-tail (loli-head arg-lst))) 36 | (arg-lst-to-type-lst (loli-tail arg-lst))) 37 | (cons (to-loli-key :obj) 38 | (arg-lst-to-type-lst (loli-tail arg-lst)))))) 39 | 40 | (defun lookup-type-env (key &optional (env *TYPE-ENV*)) 41 | (if (null env) 42 | *type-obj* 43 | (if (equalp (loli-obj-value key) 44 | (loli-type-class-id (car env))) 45 | (car env) 46 | (lookup-type-env key (cdr env))))) 47 | 48 | (defun loli-lambda (return-type arg-lst exp) 49 | (to-loli-lambda 50 | (make-loli-lambda-struct :return-type (lookup-type-env return-type) 51 | :arg-lst (arg-lst-to-sym-lst arg-lst) 52 | :arg-types (arg-lst-to-type-lst arg-lst) 53 | :exp exp) 54 | '())) 55 | 56 | (defconstant loli-lambda-f 57 | (to-loli-proc 58 | (make-loli-proc-struct :return-type *type-lambda* 59 | :arg-type *type-obj* 60 | :arity 3 61 | :cl-fn #'loli-lambda) 62 | '())) 63 | 64 | (provide 'loli-lambda) 65 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-main.lisp: -------------------------------------------------------------------------------- 1 | (let* ((*standard-output* (make-broadcast-stream)) 2 | (*error-output* *standard-output*)) 3 | (require 'loli-package "package") 4 | (require 'loli-repl "loli-repl")) 5 | 6 | (format *standard-output* "~%LoLi PRPR!~%LoLi is a Free Software and you can do whatever you want with it under ~%the licence GPLv3 or any later version. ~%") 7 | 8 | (in-package #:loli) 9 | 10 | (loli-repl) 11 | 12 | (sb-ext:exit) 13 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-make.lisp: -------------------------------------------------------------------------------- 1 | (require 'loli-package "package") 2 | (require 'loli-env "loli-env") 3 | (require 'loli-obj "loli-obj") 4 | (require 'loli-prim "loli-prim") 5 | (require 'loli-read "loli-read") 6 | (require 'loli-repl "loli-repl") 7 | (require 'loli-type-class "loli-typeclass") 8 | 9 | (compile-file "loli-main" :output-file #P"loli") 10 | 11 | (sb-ext:exit) 12 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-obj.lisp: -------------------------------------------------------------------------------- 1 | (require 'loli-package "package") 2 | (require 'loli-type-class "loli-typeclass") 3 | 4 | (in-package #:loli) 5 | 6 | (defstruct loli-obj 7 | value 8 | (loli-type *type-obj* :type loli-type-class) 9 | env) 10 | 11 | (defun to-loli-sym (value &optional (env '())) 12 | (make-loli-obj 13 | :value value 14 | :loli-type *type-sym* 15 | :env env)) 16 | 17 | (defun to-loli-fn (value &optional (env '())) 18 | (make-loli-obj 19 | :value value 20 | :loli-type *type-fn* 21 | :env env)) 22 | 23 | (defun to-loli-obj (value &optional (env '())) 24 | (make-loli-obj 25 | :value value 26 | :loli-type *type-obj* 27 | :env env)) 28 | 29 | (defun to-loli-flt (value &optional (env '())) 30 | (make-loli-obj 31 | :value value 32 | :loli-type *type-flt* 33 | :env env)) 34 | 35 | (defun to-loli-int (value &optional (env '())) 36 | (make-loli-obj 37 | :value value 38 | :loli-type *type-int* 39 | :env env)) 40 | 41 | (defun to-loli-key (value &optional (env '())) 42 | (make-loli-obj 43 | :value value 44 | :loli-type *type-key* 45 | :env env)) 46 | 47 | (defun to-loli-num (value &optional (env '())) 48 | (make-loli-obj 49 | :value value 50 | :loli-type *type-num* 51 | :env env)) 52 | 53 | (defun to-loli-bool (value &optional (env '())) 54 | (make-loli-obj 55 | :value value 56 | :loli-type *type-bool* 57 | :env env)) 58 | 59 | (defun to-loli-char (value &optional (env '())) 60 | (make-loli-obj 61 | :value value 62 | :loli-type *type-char* 63 | :env env)) 64 | 65 | (defun to-loli-string (value &optional (env '())) 66 | (make-loli-obj 67 | :value value 68 | :loli-type *type-string* 69 | :env env)) 70 | 71 | (defun to-loli-cons (value &optional (env '())) 72 | (make-loli-obj 73 | :value value 74 | :loli-type *type-cons* 75 | :env env)) 76 | 77 | (defun to-loli-lambda (value &optional (env '())) 78 | (make-loli-obj 79 | :value value 80 | :loli-type *type-lambda* 81 | :env env)) 82 | 83 | (defun to-loli-proc (value &optional (env '())) 84 | (make-loli-obj 85 | :value value 86 | :loli-type *type-proc* 87 | :env env)) 88 | 89 | (defconstant loli-nil 90 | (to-loli-sym 'nil '())) 91 | 92 | (defconstant loli-t 93 | (to-loli-sym 't '())) 94 | 95 | (defconstant loli-true 96 | (to-loli-bool :true '())) 97 | 98 | (defconstant loli-false 99 | (to-loli-bool :false '())) 100 | 101 | (defun type-id-to-type (type-id &optional (env *TYPE-ENV*)) 102 | (if (null env) 103 | NIL 104 | (if (equalp (loli-obj-value type-id) 105 | (loli-type-class-id (car env))) 106 | (car env) 107 | (type-id-to-type type-id (cdr env))))) 108 | 109 | (provide 'loli-obj) 110 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-prim.lisp: -------------------------------------------------------------------------------- 1 | (require 'loli-package "package") 2 | (require 'loli-obj "loli-obj") 3 | (require 'loli-type-class "loli-typeclass") 4 | 5 | (in-package #:loli) 6 | 7 | (defstruct loli-proc-struct 8 | (return-type *type-obj* :type loli-type-class) 9 | (arg-type *type-obj* :type loli-type-class) 10 | (arity 0 :type integer) 11 | (cl-fn nil :type function)) 12 | 13 | ;;Cons Operator 14 | (defstruct loli-cons-struct 15 | (head loli-nil :type loli-obj) 16 | (tail loli-nil :type loli-obj)) 17 | 18 | (defun loli-cons (head &optional (tail loli-nil)) 19 | (to-loli-cons 20 | (make-loli-cons-struct :head head :tail tail) '())) 21 | 22 | (defun loli-head (o) 23 | (if (loli-obj-p o) 24 | (if (loli-cons-struct-p (loli-obj-value o)) 25 | (loli-cons-struct-head (loli-obj-value o)) 26 | (format t "~A is not loli-cons" o)) 27 | 'ERR-NOT-LOLI-OBJ)) 28 | 29 | (defun loli-tail (o) 30 | (if (loli-obj-p o) 31 | (if (loli-cons-struct-p (loli-obj-value o)) 32 | (loli-cons-struct-tail (loli-obj-value o)) 33 | (format t "~A is not loli-cons" o)) 34 | 'ERR-NOT-LOLI-OBJ)) 35 | 36 | (defconstant loli-cons-f 37 | (to-loli-proc 38 | (make-loli-proc-struct :return-type *type-cons* :arg-type *type-obj* 39 | :arity 2 :cl-fn #'loli-cons) 40 | '())) 41 | 42 | (defconstant loli-head-f 43 | (to-loli-proc 44 | (make-loli-proc-struct :return-type *type-obj* :arg-type *type-cons* 45 | :arity 1 :cl-fn #'loli-head) 46 | '())) 47 | 48 | (defconstant loli-tail-f 49 | (to-loli-proc 50 | (make-loli-proc-struct :return-type *type-obj* :arg-type *type-cons* 51 | :arity 1 :cl-fn #'loli-tail) 52 | '())) 53 | 54 | ;;Number operator 55 | (defun loli-num-eq (a b) 56 | (if (and (sub-type-p (loli-obj-loli-type a) *type-num*) 57 | (sub-type-p (loli-obj-loli-type b) *type-num*)) 58 | (if (= (loli-obj-value a) (loli-obj-value b)) 59 | loli-true 60 | loli-false))) 61 | 62 | (defun loli-num-greater-than (a b) 63 | (if (and (sub-type-p (loli-obj-loli-type a) *type-num*) 64 | (sub-type-p (loli-obj-loli-type b) *type-num*)) 65 | (if (> (loli-obj-value a) (loli-obj-value b)) 66 | loli-true 67 | loli-false))) 68 | 69 | (defun loli-num-less-than (a b) 70 | (if (and (sub-type-p (loli-obj-loli-type a) *type-num*) 71 | (sub-type-p (loli-obj-loli-type b) *type-num*)) 72 | (if (< (loli-obj-value a) (loli-obj-value b)) 73 | loli-true 74 | loli-false))) 75 | 76 | (defconstant loli-num-eq-f 77 | (to-loli-proc 78 | (make-loli-proc-struct :return-type *type-bool* :arg-type *type-num* :arity 2 :cl-fn #'loli-num-eq) 79 | '())) 80 | 81 | (defconstant loli-num-greater-f 82 | (to-loli-proc 83 | (make-loli-proc-struct :return-type *type-bool* :arg-type *type-num* :arity 2 :cl-fn #'loli-num-greater-than) 84 | '())) 85 | 86 | (defconstant loli-num-less-f 87 | (to-loli-proc 88 | (make-loli-proc-struct :return-type *type-bool* :arg-type *type-num* :arity 2 :cl-fn #'loli-num-less-than) 89 | '())) 90 | 91 | ;;Arithmatic 92 | (defun loli-add (a b) 93 | (if (or (sub-type-p (loli-obj-loli-type a) *type-flt*) 94 | (sub-type-p (loli-obj-loli-type b) *type-flt*)) 95 | (to-loli-flt 96 | (+ (loli-obj-value a) (loli-obj-value b)) 97 | '()) 98 | (to-loli-int 99 | (+ (loli-obj-value a) (loli-obj-value b)) 100 | '()))) 101 | 102 | (defun loli-sub (a b) 103 | (if (or (sub-type-p (loli-obj-loli-type a) *type-flt*) 104 | (sub-type-p (loli-obj-loli-type b) *type-flt*)) 105 | (to-loli-flt 106 | (- (loli-obj-value a) (loli-obj-value b)) 107 | '()) 108 | (to-loli-int 109 | (- (loli-obj-value a) (loli-obj-value b)) 110 | '()))) 111 | 112 | (defun loli-mul (a b) 113 | (if (or (sub-type-p (loli-obj-loli-type a) *type-flt*) 114 | (sub-type-p (loli-obj-loli-type b) *type-flt*)) 115 | (to-loli-flt 116 | (* (loli-obj-value a) (loli-obj-value b)) 117 | '()) 118 | (to-loli-int 119 | (* (loli-obj-value a) (loli-obj-value b)) 120 | '()))) 121 | 122 | (defun loli-div (a b) 123 | (if (or (sub-type-p (loli-obj-loli-type a) *type-flt*) 124 | (sub-type-p (loli-obj-loli-type b) *type-flt*)) 125 | (to-loli-flt 126 | (/ (loli-obj-value a) (loli-obj-value b)) 127 | '()) 128 | (to-loli-int 129 | (/ (loli-obj-value a) (loli-obj-value b)) 130 | '()))) 131 | 132 | (defconstant loli-add-f 133 | (to-loli-proc 134 | (make-loli-proc-struct :return-type *type-num* :arg-type *type-num* 135 | :arity 2 :cl-fn #'loli-add) 136 | '())) 137 | 138 | (defconstant loli-sub-f 139 | (to-loli-proc 140 | (make-loli-proc-struct :return-type *type-num* :arg-type *type-num* 141 | :arity 2 :cl-fn #'loli-sub) 142 | '())) 143 | 144 | (defconstant loli-mul-f 145 | (to-loli-proc 146 | (make-loli-proc-struct :return-type *type-num* :arg-type *type-num* 147 | :arity 2 :cl-fn #'loli-mul) 148 | '())) 149 | 150 | (defconstant loli-div-f 151 | (to-loli-proc 152 | (make-loli-proc-struct :return-type *type-num* :arg-type *type-num* 153 | :arity 2 :cl-fn #'loli-div) 154 | '())) 155 | 156 | ;;Bool Operator 157 | (defun loli-and (a b) 158 | (if (and (sub-type-p (loli-obj-loli-type a) *type-bool*) 159 | (sub-type-p (loli-obj-loli-type b) *type-bool*)) 160 | (if (and (equalp (loli-obj-value a) :true) 161 | (equalp (loli-obj-value b) :true)) 162 | loli-true 163 | loli-false))) 164 | 165 | (defun loli-or (a b) 166 | (if (and (sub-type-p (loli-obj-loli-type a) *type-bool*) 167 | (sub-type-p (loli-obj-loli-type b) *type-bool*)) 168 | (if (or (equalp (loli-obj-value a) :true) 169 | (equalp (loli-obj-value b) :true)) 170 | loli-true 171 | loli-false))) 172 | 173 | (defun loli-not (a) 174 | (if (and (sub-type-p (loli-obj-loli-type a) *type-bool*) 175 | (equalp (loli-obj-value a) :false)) 176 | loli-true 177 | loli-false)) 178 | 179 | (defconstant loli-and-f 180 | (to-loli-proc 181 | (make-loli-proc-struct :return-type *type-bool* :arg-type *type-bool* 182 | :arity 2 :cl-fn #'loli-and) 183 | '())) 184 | 185 | (defconstant loli-or-f 186 | (to-loli-proc 187 | (make-loli-proc-struct :return-type *type-bool* :arg-type *type-bool* 188 | :arity 2 :cl-fn #'loli-or) 189 | '())) 190 | 191 | (defconstant loli-not-f 192 | (to-loli-proc 193 | (make-loli-proc-struct :return-type *type-bool* :arg-type *type-obj* 194 | :arity 1 :cl-fn #'loli-not) 195 | '())) 196 | 197 | ;;Misc 198 | (defconstant loli-quit-f 199 | (to-loli-proc 200 | (make-loli-proc-struct :return-type *type-obj* :arg-type *type-obj* 201 | :arity 0 :cl-fn #'sb-ext:exit) 202 | '())) 203 | 204 | (provide 'loli-prim) 205 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-read.lisp: -------------------------------------------------------------------------------- 1 | (require 'loli-package "package") 2 | (require 'loli-obj "loli-obj") 3 | (require 'loli-prim "loli-prim") 4 | (require 'loli-type-class "loli-typeclass") 5 | 6 | (in-package #:loli) 7 | 8 | (defun loli-read-list (lst &optional (env '())) 9 | (loli-cons (loli-read-single-obj (car lst) env) 10 | (loli-read-single-obj (cdr lst) env))) 11 | 12 | (defun loli-read-single-obj (cl-obj &optional (env '())) 13 | (if (null cl-obj) 14 | loli-nil 15 | (typecase cl-obj 16 | ((or integer 17 | bit 18 | bignum 19 | fixnum) (to-loli-int cl-obj env)) 20 | ((or float 21 | single-float 22 | double-float 23 | short-float 24 | long-float) (to-loli-flt cl-obj env)) 25 | (number (to-loli-num cl-obj env)) 26 | (string (to-loli-string cl-obj env)) 27 | (character (to-loli-char cl-obj env)) 28 | (keyword 29 | (if (or (equal cl-obj :true) 30 | (equal cl-obj :false)) 31 | (to-loli-bool cl-obj env) 32 | (to-loli-key cl-obj env))) 33 | (list (loli-read-list cl-obj env)) 34 | (symbol (to-loli-sym cl-obj env))))) 35 | 36 | (defun loli-read-from-string (str &optional (env '())) 37 | (loli-read-single-obj (read-from-string str) env)) 38 | 39 | (defun loli-validate-input (str &optional (p 0) (q t)) 40 | (loop for c across str 41 | do 42 | (cond 43 | ((equal c #\() 44 | (if q 45 | (setq p (1+ p)))) 46 | ((equal c #\)) 47 | (if q 48 | (if (>= p 1) 49 | (setq p (1- p)) 50 | (return-from loli-validate-input 'UNMATCHED-PARENTHESIS)))) 51 | ((equal c #\") 52 | (setq q (not q))))) 53 | (return-from loli-validate-input (and q (= 0 p)))) 54 | 55 | (defun loli-get-input (&optional (in-stream *standard-input*)) 56 | (let* ((tmp (read-line in-stream)) 57 | (stat (loli-validate-input tmp))) 58 | (if (equal stat 'UNMATCHED-PARENTHESIS) 59 | (return-from loli-get-input 'UNIMPLEMENTED-ERROR) 60 | (loop while (not stat) 61 | do (setq tmp (concatenate 'string tmp (read-line in-stream)) 62 | stat (loli-validate-input tmp)))) 63 | (return-from loli-get-input tmp))) 64 | 65 | (provide 'loli-read) 66 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-repl.lisp: -------------------------------------------------------------------------------- 1 | (require 'loli-package "package") 2 | (require 'loli-obj "loli-obj") 3 | (require 'loli-prim "loli-prim") 4 | (require 'loli-lambda "loli-lambda") 5 | (require 'loli-type-class "loli-typeclass") 6 | (require 'loli-env "loli-env") 7 | (require 'loli-read "loli-read") 8 | (require 'loli-error "loli-error") 9 | 10 | (in-package #:loli) 11 | 12 | (defun loli-get-new-value () 13 | (format *standard-output* "New Value: ") 14 | (multiple-value-list (loli-read-from-string (loli-get-input)))) 15 | 16 | (defun loli-symbol-not-bound-debug (obj env) 17 | (format *standard-output* "Debug:") 18 | (loli-output obj) 19 | (format *standard-output* "~%~%") 20 | (if 21 | (or (not (equal loli-nil (loli-lookup obj env))) 22 | (equal (loli-obj-value obj) 't) 23 | (equal (loli-obj-value obj) 'nil)) 24 | obj 25 | (restart-case 26 | (cerror "Symbol not bound" 'loli-err-symbol-not-bound :err-obj obj :err-env env) 27 | (use-value (new-value) 28 | :report "Enter a new value" 29 | :interactive loli-get-new-value 30 | (loli-symbol-not-bound-debug new-value env))))) 31 | 32 | (defun handle-loli-symbol-not-bound (condition) 33 | (when (typep condition 'loli-err-symbol-not-bound) 34 | (loli-symbol-not-bound-debug (err-obj condition) (err-env condition)))) 35 | 36 | (defun loli-eval-sym (sym &optional (env *TOP-ENV*)) 37 | (handler-bind ((loli-err-symbol-not-bound #'handle-loli-symbol-not-bound)) 38 | (cond 39 | ((equalp (loli-obj-value sym) 'nil) 40 | (return-from loli-eval-sym loli-nil)) 41 | ((equalp (loli-obj-value sym) 't) 42 | (return-from loli-eval-sym loli-t)) 43 | ((and (null env) (null (loli-obj-env sym))) 44 | (progn 45 | (format *standard-output* "BOTH NULL~%") 46 | (return-from loli-eval-sym 47 | (loli-eval-sym 48 | (loli-symbol-not-bound-debug sym env) 49 | env)))) 50 | ((not (null env)) 51 | (let ((r (loli-lookup sym env))) 52 | (if (not (equal r loli-nil)) 53 | (return-from loli-eval-sym (loli-head r)) 54 | (progn 55 | (format *standard-output* "Outer env err~%") 56 | (return-from loli-eval-sym 57 | (loli-eval-sym 58 | (loli-symbol-not-bound-debug sym env) 59 | env)))))) 60 | ((not (null (loli-obj-env sym))) 61 | (let ((r (loli-lookup sym (loli-obj-env sym)))) 62 | (if (not (equal r loli-nil)) 63 | (return-from loli-eval-sym (loli-head r)) 64 | (progn 65 | (loli-output (loli-obj-env sym)) 66 | (format *standard-output* "Inner env err~%") 67 | (return-from loli-eval-sym 68 | (loli-eval-sym 69 | (loli-symbol-not-bound-debug sym env) 70 | env)))))) 71 | (t 72 | ; (loli-symbol-not-bound-debug sym env) 73 | )))) 74 | 75 | (defun break-loli-cons (lcons) 76 | (if (equalp lcons loli-nil) 77 | nil 78 | (cons (loli-head lcons) 79 | (break-loli-cons (loli-tail lcons))))) 80 | 81 | (defun loli-make-lambda-env (env lambda-arg v-lst) 82 | (if (equalp (loli-obj-value lambda-arg) 'nil) 83 | env 84 | (loli-cons 85 | (loli-cons 86 | (loli-head lambda-arg) 87 | (loli-head v-lst)) 88 | (loli-make-lambda-env env 89 | (loli-tail lambda-arg) 90 | (loli-tail v-lst))))) 91 | 92 | (defun loli-simple-apply (fn lst &optional (env *TOP-ENV*)) 93 | (if (sub-type-p (loli-obj-loli-type fn) *type-cons*) 94 | (setf fn (loli-head fn))) 95 | (cond 96 | ((sub-type-p (loli-obj-loli-type fn) *type-proc*) 97 | (apply (loli-proc-struct-cl-fn (loli-obj-value fn)) 98 | (break-loli-cons lst))) 99 | ((sub-type-p (loli-obj-loli-type fn) *type-lambda*) 100 | (loli-simple-eval (loli-lambda-struct-exp (loli-obj-value fn)) 101 | (loli-make-lambda-env env 102 | (loli-lambda-struct-arg-lst (loli-obj-value fn)) 103 | lst))) 104 | (t 105 | loli-nil))) 106 | 107 | (defun loli-eval-list (lst &optional (env *TOP-ENV*)) 108 | (if (equalp lst loli-nil) 109 | loli-nil 110 | (loli-cons (loli-simple-eval (loli-head lst) env) 111 | (loli-eval-list (loli-tail lst) env)))) 112 | 113 | (defun loli-eval-cons (lcons &optional (env *TOP-ENV*)) 114 | (cond ((equalp (loli-obj-value (loli-head lcons)) '\\) ;; Lambda 115 | (apply (loli-proc-struct-cl-fn (loli-obj-value loli-lambda-f)) 116 | (break-loli-cons (loli-tail lcons)))) 117 | ((equalp (loli-obj-value (loli-head lcons)) 'def) 118 | (apply (loli-proc-struct-cl-fn (loli-obj-value loli-def-f)) 119 | (break-loli-cons (loli-tail lcons))) 120 | (loli-output *TOP-ENV*) 121 | ) 122 | ((equalp (loli-obj-value (loli-head lcons)) 'set!) 123 | (apply (loli-proc-struct-cl-fn (loli-obj-value loli-set-f)) 124 | (break-loli-cons (loli-tail lcons)))) 125 | ((equalp (loli-obj-value (loli-head lcons)) 'if) ;; If 126 | (let ((tcons (loli-tail lcons))) 127 | (setf (loli-obj-env (loli-head tcons)) env) 128 | (loli-simple-eval 129 | (apply (loli-proc-struct-cl-fn (loli-obj-value loli-if-f)) 130 | (break-loli-cons (loli-cons env tcons))) 131 | env))) 132 | (t 133 | (loli-simple-apply (loli-simple-eval (loli-head lcons) env) (loli-eval-list (loli-tail lcons) env) env)))) 134 | 135 | (defun loli-simple-eval (obj &optional (env *TOP-ENV*)) 136 | (cond 137 | ((sub-type-p (loli-obj-loli-type obj) 138 | *type-sym*) 139 | (loli-eval-sym obj env)) 140 | ((sub-type-p (loli-obj-loli-type obj) 141 | *type-cons*) 142 | (loli-eval-cons obj env)) 143 | (t obj))) 144 | 145 | (defun loli-if (env c then else) 146 | (if (not (equalp (loli-obj-value (loli-simple-eval c env)) (loli-obj-value loli-false))) 147 | then 148 | else)) 149 | 150 | (defconstant loli-if-f 151 | (to-loli-proc 152 | (make-loli-proc-struct :return-type *type-obj* :arg-type *type-obj* 153 | :arity 3 :cl-fn #'loli-if) 154 | '())) 155 | 156 | (defun loli-output (obj &optional (output-stream *standard-output*)) 157 | (force-output output-stream) 158 | (cond 159 | ((sub-type-p (loli-obj-loli-type obj) 160 | *type-fn*) 161 | (cond 162 | ((sub-type-p (loli-obj-loli-type obj) 163 | *type-proc*) 164 | (format output-stream " ~A>" 165 | (make-list 166 | (loli-proc-struct-arity (loli-obj-value obj)) 167 | :initial-element 168 | (loli-type-class-id 169 | (loli-proc-struct-arg-type (loli-obj-value obj)))) 170 | (loli-type-class-id 171 | (loli-proc-struct-return-type (loli-obj-value obj))))) 172 | ((sub-type-p (loli-obj-loli-type obj) 173 | *type-lambda*) 174 | (format output-stream " ~A>" 175 | (loop for a in (loli-lambda-struct-arg-types (loli-obj-value obj)) 176 | collect (loli-obj-value a)) 177 | (loli-type-class-id 178 | (loli-lambda-struct-return-type (loli-obj-value obj))))) 179 | (t 180 | (format output-stream "")))) 181 | ((sub-type-p (loli-obj-loli-type obj) 182 | *type-cons*) 183 | (format output-stream "(") 184 | (loli-output (loli-head obj) output-stream) 185 | (if (sub-type-p (loli-obj-loli-type (loli-tail obj)) 186 | *type-cons*) 187 | (progn 188 | (format output-stream " ") 189 | (loli-output (loli-tail obj) output-stream) 190 | (format output-stream ")")) 191 | (progn 192 | (format output-stream " . ") 193 | (loli-output (loli-tail obj) output-stream) 194 | (format output-stream ")")))) 195 | (t 196 | (format output-stream "~A" (loli-obj-value obj))))) 197 | 198 | 199 | (defun loli-rep (&optional (in-stream *standard-input*) (env *TOP-ENV*) (out-stream *standard-output*)) 200 | (let ((i (loli-get-input in-stream))) 201 | (if (equalp i "") 202 | nil 203 | (let ((o (loli-simple-eval (loli-read-from-string i env) env))) 204 | (loli-output o out-stream))))) 205 | 206 | (defun loli-repl (&optional 207 | (in-stream *standard-input*) 208 | (env *TOP-ENV*) 209 | (out-stream *standard-output*)) 210 | (do () 211 | (nil 'QUIT) 212 | (format out-stream "~%LoLi > ") 213 | (force-output out-stream) 214 | (loli-rep in-stream env out-stream))) 215 | 216 | (provide 'loli-repl) 217 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-test.lisp: -------------------------------------------------------------------------------- 1 | (require 'loli-package "package") 2 | (require 'loli-obj "loli-obj") 3 | (require 'loli-prim "loli-prim") 4 | (require 'loli-env "loli-env") 5 | (require 'loli-repl "loli-repl") 6 | (require 'loli-type-class "loli-typeclass") 7 | 8 | (in-package #:loli) 9 | 10 | (defparameter *TEST-ENV* loli-nil) 11 | 12 | (setf *TEST-ENV* 13 | (loli-cons 14 | (loli-cons (to-loli-sym "TEST") 15 | (to-loli-int 151)) 16 | *TEST-ENV*)) 17 | 18 | (setf *TEST-ENV* 19 | (loli-cons 20 | (loli-cons (to-loli-sym "AAA") 21 | (to-loli-sym "AAA")) 22 | *TEST-ENV*)) 23 | 24 | (setf *TEST-ENV* 25 | (loli-cons 26 | (loli-cons (to-loli-sym "AAA") 27 | (to-loli-int "111")) 28 | *TEST-ENV*)) 29 | 30 | (loli-lookup (to-loli-sym "AAA") 31 | *TEST-ENV*) 32 | 33 | (loli-lookup (to-loli-sym "A") 34 | *TEST-ENV*) 35 | 36 | (defparameter *TEST-LAMBDA* 37 | (to-loli-lambda 38 | (make-loli-lambda-struct :return-type *type-obj* 39 | :arg-types (list *type-obj* *type-int*)))) 40 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-testcases.lisp: -------------------------------------------------------------------------------- 1 | (require 'loli-package "package") 2 | (require 'loli-type-class "loli-typeclass") 3 | (require 'loli-obj "loli-obj") 4 | (require 'loli-eval "loli-eval") 5 | 6 | (in-package #:loli) 7 | 8 | (format *standard-output* "~A~%" (sub-type-p (loli-obj-loli-type loli-true) *type-key*)) 9 | 10 | (format *standard-output* "~A~%" (loli-simple-eval loli-false)) 11 | -------------------------------------------------------------------------------- /src/CL-Backend/loli-typeclass.lisp: -------------------------------------------------------------------------------- 1 | (require 'loli-package "package") 2 | 3 | (in-package #:loli) 4 | 5 | (defstruct loli-type-class 6 | name 7 | id 8 | parent) 9 | 10 | (defparameter *type-obj* 11 | (make-loli-type-class :name "Object" :id :OBJ :parent nil) "The Basic Type of LoLi") 12 | (defparameter *type-num* 13 | (make-loli-type-class :name "Number" :id :NUM :parent *type-obj*) "The Generic Type Of Number in LoLi") 14 | (defparameter *type-int* 15 | (make-loli-type-class :name "Integer" :id :INT :parent *type-num*) "The Integer Type in LoLi") 16 | (defparameter *type-flt* 17 | (make-loli-type-class :name "Float" :id :FLT :parent *type-num*) "The Float Type in LoLi") 18 | (defparameter *type-sym* 19 | (make-loli-type-class :name "Symbol" :id :SYM :parent *type-obj*) "The Symbol Type in LoLi") 20 | (defparameter *type-key* 21 | (make-loli-type-class :name "Keyword" :id :KEY :parent *type-obj*) "The Keyword Type in LoLi") 22 | (defparameter *type-cons* 23 | (make-loli-type-class :name "Cons" :id :CONS :parent *type-obj*) "The CONS (Pair) Type in LoLi") 24 | (defparameter *type-fn* 25 | (make-loli-type-class :name "Function" :id :FN :parent *type-obj*) "The Generic Type of Function in LoLi") 26 | (defparameter *type-lambda* 27 | (make-loli-type-class :name "Lambda" :id :LAMBDA :parent *type-fn*) "The Lambda Type in LoLi") 28 | (defparameter *type-proc* 29 | (make-loli-type-class :name "Procedure" :id :PROC :parent *type-fn*) "The Primitive Procedure Type in LoLi") 30 | (defparameter *type-char* 31 | (make-loli-type-class :name "Character" :id :CHAR :parent *type-obj*) "The Character Type in LoLi") 32 | (defparameter *type-string* 33 | (make-loli-type-class :name "String" :id :STR :parent *type-obj*) "The String Type in LoLi") 34 | (defparameter *type-bool* 35 | (make-loli-type-class :name "Boolean" :id :BOOL :parent *type-key*) "The Boolean Type in LoLi") 36 | 37 | (defun sub-type-p (type-a type-b) 38 | ; (format *standard-output* "~A ~A" type-a type-b) 39 | (if (or (null type-a) (null type-b)) 40 | 'NULL-ARG 41 | (if (equalp type-b *type-obj*) 42 | t 43 | (if (equalp type-a *type-obj*) 44 | nil 45 | (if (equalp type-a type-b) 46 | t 47 | (sub-type-p (loli-type-class-parent type-a) type-b)))))) 48 | 49 | (defparameter *TYPE-ENV* 50 | (list 51 | *type-obj* 52 | *type-fn* 53 | *type-flt* 54 | *type-int* 55 | *type-key* 56 | *type-num* 57 | *type-sym* 58 | *type-bool* 59 | *type-char* 60 | *type-string* 61 | *type-cons* 62 | *type-lambda* 63 | *type-proc*) 64 | "The Global Environment Contains All Types of LoLi") 65 | 66 | (provide 'loli-type-class) 67 | -------------------------------------------------------------------------------- /src/CL-Backend/package.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:cl-user) 2 | 3 | (defpackage #:loli 4 | (:use :cl)) 5 | 6 | (provide 'loli-package) 7 | -------------------------------------------------------------------------------- /src/Erl-Backend/README.mkd: -------------------------------------------------------------------------------- 1 | #LoLi Erlang-Backend 2 | 3 | Since I'm learning Erlang right now, this is supposed to be an exercise project. 4 | -------------------------------------------------------------------------------- /src/Erl-Backend/loli_repl.erl: -------------------------------------------------------------------------------- 1 | -module(loli_repl). 2 | -export([main/0, repl/1]). 3 | 4 | main()-> 5 | repl(0). 6 | 7 | gen_blank(N) when N >= 1 -> 8 | string:concat(" ", gen_blank(N - 1)); 9 | 10 | gen_blank(0) -> 11 | "". 12 | 13 | repl(S) -> 14 | io:format("LoLi> ~s", [gen_blank(string:len(S))]), 15 | I = io:get_line(""), 16 | N = string:concat(I, S), 17 | repl(N). 18 | 19 | -------------------------------------------------------------------------------- /src/Erl-Backend/loli_typeclass.erl: -------------------------------------------------------------------------------- 1 | -module(loli_typeclass). 2 | -export([new_type/3, sub_type_p/2, new_related_type/3, new_compound_type/2]). 3 | 4 | new_type(Name, Id, Parent) -> {'loli_basic_type', {Name, Id, Parent}}. 5 | 6 | new_related_type(Fn, Base, Target) -> {'loli_related_type', {Fn, Base, Target}}. 7 | 8 | new_compound_type(R, S) -> {'loli_compund_type', {R, S}}. 9 | 10 | sub_type_p(_ = {'loli_basic_type', {_, _, _}}, _ = {'loli_basic_type', {"Object", obj, nil}}) -> 11 | true; 12 | 13 | sub_type_p(_ = {'loli_basic_type', {X, Y, Z}}, _ = {'loli_basic_type', {X, Y, Z}}) -> 14 | true; 15 | 16 | sub_type_p(_ = {'loli_basic_type', {"Object", obj, nil}}, _ = {'loli_basic_type', {_, _, _}}) -> 17 | false; 18 | 19 | sub_type_p(_ = {'loli_basic_type', {_, _, Parent}}, T = {'loli_basic_type', {_, _, _}}) -> 20 | sub_type_p(Parent, T); 21 | 22 | sub_type_p(_ = {'loli_compound_type', {X, Y}}, _ = {'loli_compound_type', {X, Y}}) -> 23 | true; 24 | 25 | sub_type_p(_ = {'loli_compound_type', {A = {'loli_basic_type', {_, _, _}}, B = {'loli_basic_type', {_, _, _}}}}, 26 | _ = {'loli_compound_type', {C = {'loli_basic_type', {_, _, _}}, D = {'loli_basic_type', {_, _, _}}}}) -> 27 | sub_type_p(A, C) and sub_type_p(B, D); 28 | 29 | sub_type_p(_, _) -> 30 | false. 31 | -------------------------------------------------------------------------------- /src/LoLi/README.mkd: -------------------------------------------------------------------------------- 1 | LoLi 2 | ==== 3 | 4 | The first version of the LoLi interpreter, the development is stopped. 5 | -------------------------------------------------------------------------------- /src/LoLi/currentc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LoLi-Lang/LoLi/9306a531a42df9e81b75de4bc278aa8dc9c22a3f/src/LoLi/currentc -------------------------------------------------------------------------------- /src/LoLi/currentg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LoLi-Lang/LoLi/9306a531a42df9e81b75de4bc278aa8dc9c22a3f/src/LoLi/currentg -------------------------------------------------------------------------------- /src/LoLi/functions.loli: -------------------------------------------------------------------------------- 1 | (def .. (\ (start end) 2 | (if (eq? start end) 3 | (cons end nil) 4 | (cons start (.. (add1 start) end))))) 5 | 6 | (def null? (\ (obj) 7 | (eq? nil obj))) 8 | 9 | (def append (\ (lsta lstb) 10 | (if (null? lsta) 11 | lstb 12 | (cons (head lsta) (append (tail lsta) lstb))))) 13 | 14 | (def pow (\ (base pow) 15 | (if (eq? pow 0) 16 | 1 17 | (* base (pow base (- pow 1)))))) 18 | -------------------------------------------------------------------------------- /src/LoLi/header/loli.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli.h 5 | * 6 | * Description: Headers of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 05/04/2014 05:28:39 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_HEADER_ 20 | #define __LOLI_HEADER_ 21 | 22 | #include "loli_types.h" 23 | #include "loli_symbols.h" 24 | #include "loli_cons.h" 25 | #include "loli_prim.h" 26 | #include "loli_list.h" 27 | #include "loli_ast.h" 28 | #include "loli_output.h" 29 | #include "loli_env.h" 30 | #include "loli_repl.h" 31 | #include "loli_read.h" 32 | #include "loli_parser.h" 33 | #include "loli_apply.h" 34 | #include "loli_cbmi.h" 35 | #include "loli_eval.h" 36 | #include "loli_parser.h" 37 | #include "loli_gui.h" 38 | #include "loli_lambda.h" 39 | #include "loli_def.h" 40 | #include "loli_file.h" 41 | #include "loli_set.h" 42 | #include "loli_cond.h" 43 | #include "loli_let.h" 44 | //#include "loli_stack.h" 45 | 46 | static loliObj* top_env = cons(nil, nil); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_apply.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_apply.h 5 | * 6 | * Description: Apply Of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 05/13/2014 06:35:42 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_APPLY_ 20 | #define __LOLI_APPLY_ 21 | 22 | #include "loli.h" 23 | 24 | extern loliObj* apply(loliObj* proc, loliObj* obj, loliObj* env); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_ast.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_ast.h 5 | * 6 | * Description: AST of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/14/2014 01:38:03 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_AST_ 20 | #define __LOLI_AST_ 21 | 22 | #include "loli_types.h" 23 | 24 | #include 25 | 26 | enum loliNodeType { 27 | NODE, 28 | LEAF 29 | }; 30 | 31 | struct loliNode { 32 | loliNodeType type; 33 | loliNode* parent; 34 | loliObj* obj; 35 | loliNode* child; 36 | 37 | loliNode(loliObj* o){ 38 | obj = o; 39 | } 40 | }; 41 | 42 | extern loliNode* nilNode; 43 | 44 | extern loliNode* toTree(loliObj* exp, loliNode* parent); 45 | extern loliNode* toTree(loliObj* exp); 46 | extern std::string nodeToString(loliNode* tree); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_cbmi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_cbmi.h 5 | * 6 | * Description: The Context Based Meaning Inference Header 7 | * 8 | * Version: 1.0 9 | * Created: 04/27/2014 02:21:14 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | 20 | #ifndef __LOLI_CBMI_ 21 | #define __LOLI_CBMI_ 22 | 23 | #include "loli_types.h" 24 | 25 | extern loliObj* getType(loliType type, loliObj* obj, loliObj* env); 26 | 27 | extern loliObj* get_cons(loliObj* sym, loliObj* env); 28 | extern loliObj* get_int(loliObj* sym, loliObj* env); 29 | extern loliObj* get_flt(loliObj* sym, loliObj* env); 30 | extern loliObj* get_sym(loliObj* sym, loliObj* env); 31 | extern loliObj* get_proc(loliObj* sym, loliObj* env); 32 | extern loliObj* get_lambda(loliObj* sym, loliObj* env); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_cond.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_cond.h 5 | * 6 | * Description: Header of Cond 7 | * 8 | * Version: 1.0 9 | * Created: 06/09/2014 05:50:44 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_COND_ 20 | #define __LOLI_COND_ 21 | 22 | #include "loli.h" 23 | 24 | extern loliObj* prim_if(loliObj* exp, loliObj* env); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_cons.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_cons.h 5 | * 6 | * Description: Functions of operating cons 7 | * 8 | * Version: 1.0 9 | * Created: 04/05/2014 02:15:01 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_CONS_ 20 | #define __LOLI_CONS_ 21 | 22 | #include "loli_types.h" 23 | 24 | extern loliObj* cons(loliObj* hd, loliObj* tl); 25 | extern loliObj* prim_cons(loliObj* exp, loliObj* env); 26 | extern loliObj* head(loliObj* cons); 27 | extern loliObj* tail(loliObj* cons); 28 | extern loliObj* prim_head(loliObj* cons, loliObj* env); 29 | extern loliObj* prim_tail(loliObj* cons, loliObj* env); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_def.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_def.h 5 | * 6 | * Description: Basic define function 7 | * 8 | * Version: 1.0 9 | * Created: 06/04/2014 02:09:15 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_DEF_ 20 | #define __LOLI_DEF_ 21 | 22 | #include "loli.h" 23 | 24 | extern loliObj* prim_def(loliObj* exp); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_env.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_env.h 5 | * 6 | * Description: Environment of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/17/2014 02:34:28 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | 20 | #ifndef __LOLI_ENV_ 21 | #define __LOLI_ENV_ 22 | 23 | #include "loli_types.h" 24 | #include "loli_symbols.h" 25 | #include "loli_cons.h" 26 | #include "loli_ast.h" 27 | #include "loli.h" 28 | 29 | //extern loliObj* top_env; 30 | extern loliObj* mkEnvProc(loliObj* sym, loliObj* type, loliObj* proc); 31 | extern loliObj* addToEnv(loliObj* env, loliObj* obj); 32 | extern loliObj* lookup(loliObj* sym, loliObj* env); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_eval.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_eval.h 5 | * 6 | * Description: Eval Header of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/27/2014 02:10:03 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_EVAL_ 20 | #define __LOLI_EVAL_ 21 | 22 | #include "loli.h" 23 | 24 | extern loliObj* eval(loliObj* obj, loliObj* env); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_file.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_file.h 5 | * 6 | * Description: File Reader of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/04/2014 08:04:52 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_FILE_ 20 | #define __LOLI_FILE_ 21 | 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include "loli.h" 28 | 29 | extern bool readFile(std::string fileName, loliObj* env); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_gc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_gc.h 5 | * 6 | * Description: GC of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/17/2014 09:34:31 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: C.Hu (), h@itis.ga 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_GC_ 20 | #define __LOLI_GC_ 21 | 22 | #include "../gc/include/gc.h" 23 | #include "../gc/include/gc_cpp.h" 24 | #include "../gc/include/gc_allocator.h" 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_gui.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_gui.h 5 | * 6 | * Description: Gui header of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 05/23/2014 10:36:33 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_GUI_ 20 | #define __LOLI_GUI_ 21 | 22 | extern int guitest(int argc, char* argv[]); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_lambda.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_lambda.h 5 | * 6 | * Description: Lambda of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/02/2014 09:52:37 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_LAMBDA_ 20 | #define __LOLI_LAMBDA_ 21 | 22 | #include "loli.h" 23 | 24 | extern loliObj* mklambda(loliObj* exp); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_let.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_let.h 5 | * 6 | * Description: Let of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/16/2014 09:12:19 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_LET_ 20 | #define __LOLI_LET_ 21 | 22 | #include "loli.h" 23 | 24 | extern loliObj* prim_let(loliObj* exp, loliObj* env); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_list.h 5 | * 6 | * Description: The primitive list operations of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/08/2014 11:17:14 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | 20 | #ifndef __LOLI_LIST_ 21 | #define __LOLI_LIST_ 22 | 23 | #include "loli_types.h" 24 | #include "loli_cons.h" 25 | #include "loli_symbols.h" 26 | 27 | extern loliObj* prim_length(loliObj* lst); 28 | extern loliObj* prim_append(loliObj* lst); 29 | extern loliObj* prim_list(loliObj* lst, loliObj* env); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_output.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_output.h 5 | * 6 | * Description: Header of Output 7 | * 8 | * Version: 1.0 9 | * Created: 04/19/2014 05:34:58 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_OUTPUT_ 20 | #define __LOLI_OUTPUT_ 21 | 22 | #include 23 | #include "loli_types.h" 24 | 25 | extern std::string toString(loliObj* obj); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_parser.h 5 | * 6 | * Description: Parser Header of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/27/2014 02:10:47 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_PARSER_ 20 | #define __LOLI_PARSER_ 21 | 22 | #include "loli.h" 23 | #include 24 | 25 | extern loliObj* parse(std::string exp); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_prim.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_prim.h 5 | * 6 | * Description: The primitive functions of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/07/2014 12:35:05 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_PRIM_ 20 | #define __LOLI_PRIM_ 21 | 22 | #include "loli_types.h" 23 | #include "loli_symbols.h" 24 | #include "loli_cons.h" 25 | 26 | //[NUM] -> NUM 27 | extern loliObj* proc_sum(loliObj* lst, loliObj* env); 28 | extern loliObj* proc_mul(loliObj* lst, loliObj* env); 29 | extern loliObj* proc_sub(loliObj* lst, loliObj* env); 30 | extern loliObj* proc_div(loliObj* lst, loliObj* env); 31 | 32 | //NUM -> NUM 33 | extern loliObj* proc_add1(loliObj* num, loliObj* env); 34 | extern loliObj* proc_sub1(loliObj* num, loliObj* env); 35 | 36 | //[NUM] -> NUM 37 | extern loliObj* proc_mod(loliObj* lst, loliObj* env); 38 | 39 | //[NUM] -> SYM 40 | extern loliObj* proc_greater(loliObj* lst, loliObj* env); 41 | extern loliObj* proc_lesser(loliObj* lst, loliObj* env); 42 | 43 | extern loliObj* proc_exit(loliObj* dum, loliObj* env); 44 | 45 | extern loliObj* proc_atom(loliObj* obj, loliObj* env); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_read.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_read.h 5 | * 6 | * Description: Reader of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/25/2014 11:24:58 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | 20 | #ifndef __LOLI_READ_ 21 | #define __LOLI_READ_ 22 | 23 | #include 24 | #include 25 | 26 | extern std::string readPaired(int i, bool quote); 27 | extern std::string readPaired(int i, bool quote, std::ifstream &stream); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_repl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_eval.h 5 | * 6 | * Description: Header of REPL 7 | * 8 | * Version: 1.0 9 | * Created: 04/20/2014 01:51:53 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | 20 | #ifndef __LOLI_REPL_ 21 | #define __LOLI_REPL_ 22 | 23 | #include "loli_types.h" 24 | 25 | extern void repl(loliObj* obj); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_set.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_set.h 5 | * 6 | * Description: Header of Set in LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/09/2014 10:42:09 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_SET_ 20 | #define __LOLI_SET_ 21 | 22 | #include "loli.h" 23 | 24 | extern loliObj* prim_set(loliObj* exp, loliObj* env); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_stack.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_stack.h 5 | * 6 | * Description: Stack of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/19/2014 11:29:43 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_STACK_ 20 | #define __LOLI_STACK_ 21 | 22 | #include "loli.h" 23 | 24 | #include 25 | 26 | extern loliObj loli_stack[]; 27 | extern int obj_in_stack; 28 | 29 | extern bool isStackEmpty(); 30 | extern bool isStackFull(); 31 | 32 | extern void printStack(); 33 | 34 | extern loliObj* pop(); 35 | extern void push(loliObj* obj); 36 | 37 | extern void flushStack(); 38 | 39 | extern void reverseStack(); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_symbols.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_symbols.h 5 | * 6 | * Description: The Internal Symols of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/05/2014 01:25:34 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_SYMS_ 20 | #define __LOLI_SYMS_ 21 | 22 | #include "loli_types.h" 23 | 24 | extern loliObj *nil; 25 | extern loliObj *t; 26 | extern loliObj *lambda; 27 | extern loliObj *set; 28 | extern loliObj *quote; 29 | extern loliObj *anon; 30 | extern loliObj *ldef; 31 | extern loliObj *lif; 32 | extern loliObj *llet; 33 | 34 | 35 | extern bool nilp(loliObj* o); 36 | extern void cleanUp(); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/LoLi/header/loli_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_types.h 5 | * 6 | * Description: The Type System of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/04/2014 07:47:15 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_TYPES_ 20 | #define __LOLI_TYPES_ 21 | 22 | #include 23 | 24 | enum loliType { 25 | SYM, //Symbol 26 | INT, //Integer 27 | FLT, //Float Number 28 | CONS, //Cons 29 | PROC, //Procedure 30 | CHAR, //Character 31 | STRING, //String 32 | LAMBDA, //Lambda Expression 33 | _ //Any 34 | }; 35 | 36 | struct loliObj { 37 | typedef loliObj* (procedure)(loliObj *, loliObj *); 38 | loliType type; 39 | std::string value; 40 | loliObj * head; 41 | loliObj * tail; 42 | loliObj * env; 43 | procedure * proc; 44 | 45 | //For type base cbmi 46 | loliType inType; 47 | loliType outType; 48 | 49 | loliObj(){ 50 | 51 | } 52 | 53 | loliObj(loliType tp){ 54 | type = tp; 55 | } 56 | }; 57 | 58 | extern loliObj *mksym(std::string symName); 59 | extern loliObj* mkint(int number); 60 | extern loliObj* mkflt(long double number); 61 | extern loliObj* mkproc(loliObj::procedure &proc); 62 | extern bool equals(loliObj* a, loliObj* b); 63 | extern loliObj* prim_equals(loliObj* obj, loliObj* env); 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/LoLi/loli_apply.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_apply.cpp 5 | * 6 | * Description: Apply Of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 05/13/2014 06:34:32 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "header/loli.h" 20 | 21 | #include 22 | 23 | loliObj* apply(loliObj* proc, loliObj* obj, loliObj* env){ 24 | // std::cout<<"Proc: "<type == PROC){ 26 | obj->env = env; 27 | return proc->proc(obj, env); 28 | } 29 | if(proc->type == LAMBDA){ 30 | loliObj* tmpe = env; 31 | for(loliObj* args = proc->env;!nilp(head(args));args = tail(args)){ 32 | tmpe = cons(cons(head(args), head(obj)), tmpe); 33 | // std::cout<<"Args: "<tail)<tail, tmpe); 38 | } 39 | std::cout<outType == ot) && (head(tail(procLst))->outType == ot) && \ 56 | (head(procLst)->inType == head(tail(procLst))->inType)){ 57 | std::cout<<"Error: type conflict! More than one procedure exist!"<outType != ot) && (head(tail(procLst))->outType != ot)){ 61 | std::cout<<"Error: no procedure matches the type requirement!"<outType == ot ? proc = head(procLst) : proc = head(tail(procLst)); 65 | } 66 | bool tt = true; 67 | !nilp(head(procLst)) ? proc = head(procLst) : proc = head(tail(procLst)); 68 | for(auto arg = tail(lst); tail(arg)->type == CONS; arg = tail(arg)){ 69 | if(head(arg)->type != CONS){ 70 | tt = tt && head(arg)->type == proc->inType; 71 | }else{ 72 | tt = tt && !nilp(arg, env, tt->inType); 73 | } 74 | } 75 | if(!tt){ 76 | std::cout<<"Error: some arguments don't match the requirement of the procedure!"<inType<<" needed, but not all of argmuments match"< 22 | 23 | /* 24 | * LoLi-AST Rule: 25 | * Parent Node must be Verb (Function / Lambda Expression) 26 | * Children Node must be Noun that the Verb can take (SYM / INT / FLT / Etc.) 27 | * E.g.: 28 | * V 29 | * / \ 30 | * V V 31 | * / / \ 32 | * N N N 33 | * (V (V N) (V N N)) 34 | */ 35 | 36 | loliNode* nilNode = new (UseGC)loliNode(nil); 37 | 38 | loliNode* toTree(loliObj* exp, loliNode* parent){ 39 | if(nilp(exp)){ 40 | loliNode* tmpn = nilNode; 41 | tmpn->type = LEAF; 42 | tmpn->parent = parent; 43 | tmpn->child = nilNode; 44 | return tmpn; 45 | } 46 | loliNode* tmp = new (UseGC) loliNode(head(exp)); 47 | tmp->type = NODE; 48 | tmp->parent = parent; 49 | tmp->child = toTree(tail(exp), tmp); 50 | return tmp; 51 | } 52 | 53 | loliNode* toTree(loliObj* exp){ 54 | return toTree(exp, nilNode); 55 | } 56 | 57 | std::string nodeToString(loliNode* tree){ 58 | if(tree->type == LEAF){ 59 | return "LEAF"; 60 | } 61 | return "node: " + toString(tree->obj) + " child:\n" + nodeToString(tree->child); 62 | } 63 | -------------------------------------------------------------------------------- /src/LoLi/loli_cbmi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_cbmi.cpp 5 | * 6 | * Description: The Context Based Meaning Inference 7 | * 8 | * Version: 1.0 9 | * Created: 04/27/2014 02:14:10 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "header/loli.h" 20 | 21 | #include 22 | 23 | loliObj* getType(loliType type, loliObj* sym, loliObj* env){ 24 | loliObj* tmp = lookup(sym, env); 25 | // std::cout<type == type){ 29 | return tail(head(tmp)); 30 | } 31 | } 32 | return nil; 33 | } 34 | 35 | loliObj* get_cons(loliObj* sym, loliObj* env){ 36 | return getType(CONS, head(sym), env); 37 | } 38 | 39 | loliObj* get_int(loliObj* sym, loliObj* env){ 40 | return getType(INT, head(sym), env); 41 | } 42 | 43 | loliObj* get_flt(loliObj* sym, loliObj* env){ 44 | return getType(FLT, head(sym), env); 45 | } 46 | 47 | loliObj* get_sym(loliObj* sym, loliObj* env){ 48 | return getType(SYM, head(sym), env); 49 | } 50 | 51 | loliObj* get_proc(loliObj* sym, loliObj* env){ 52 | return getType(PROC, head(sym), env); 53 | } 54 | 55 | loliObj* get_lambda(loliObj* sym, loliObj* env){ 56 | return getType(LAMBDA, head(sym), env); 57 | } 58 | 59 | loliObj* consToValued(loliObj* cons, loliObj* env){ 60 | loliObj* headOpr; 61 | if(!nilp(getType(PROC, head(cons), env))){ 62 | headOpr = getType(PROC, head(cons), env); 63 | }else if(!nilp(getType(LAMBDA, head(cons), env))){ 64 | headOpr = getType(LAMBDA, head(cons), env); 65 | }else{ 66 | std::cout<<"Error: no matching function / lambda expression found!"< 20 | 21 | #include "header/loli.h" 22 | #include "header/loli_gc.h" 23 | 24 | loliObj* cons(loliObj* hd, loliObj* tl){ //HD stands for HEAD, TL stands for TAIL 25 | loliObj * tmp = new (UseGC) loliObj(CONS); 26 | tmp->head = hd; 27 | tmp->tail = tl; 28 | return tmp; 29 | } 30 | 31 | loliObj* prim_cons(loliObj* exp, loliObj* env){ //HD stands for HEAD, TL stands for TAIL 32 | loliObj * tmp = new (UseGC) loliObj(CONS); 33 | tmp->head = head(exp); 34 | tmp->tail = head(tail(exp)); 35 | return tmp; 36 | } 37 | 38 | loliObj* head(loliObj* cons){ 39 | if(cons->type == CONS){ 40 | return cons->head; 41 | }else{ 42 | return nil; 43 | } 44 | } 45 | 46 | loliObj* tail(loliObj* cons){ 47 | if(cons->type == CONS){ 48 | return cons->tail; 49 | }else{ 50 | return nil; 51 | } 52 | } 53 | 54 | loliObj* prim_head(loliObj* cons, loliObj* env){ 55 | if(cons->type != CONS){ 56 | std::cout<<"Error! Need a CONS obj!"<type != CONS){ 64 | std::cout<<"Error! Need a CONS obj!"< 20 | 21 | #include "header/loli.h" 22 | 23 | loliObj* prim_def(loliObj* exp){ 24 | std::cout<<"Exp: "< 20 | 21 | #include "header/loli.h" 22 | 23 | //loliObj* top_env = cons(cons(cons(nil , nil), cons(cons(t , t), nil))); 24 | //loliObj* top_env = nil; 25 | 26 | loliObj* mkEnvProc(loliObj* sym, loliObj* type, loliObj* proc){ 27 | loliObj* tmp = cons(sym, cons(type, proc)); 28 | return tmp; 29 | } 30 | 31 | loliObj* addToEnv(loliObj* env, loliObj* obj){ 32 | // std::cout<<"ENV: "<value < head(obj)->value){ 37 | return cons(head(env), addToEnv(tail(env), obj)); 38 | }else{ 39 | return cons(obj, env); 40 | } 41 | } 42 | 43 | loliObj* lookup(loliObj* sym, loliObj* env){ 44 | // std::cout<<"ENV: "<value == sym->value){ 49 | return cons(head(env), lookup(sym, tail(env))); 50 | }else{ 51 | return lookup(sym, tail(env)); 52 | } 53 | } 54 | return nil; 55 | } 56 | -------------------------------------------------------------------------------- /src/LoLi/loli_eval.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_eval.cpp 5 | * 6 | * Description: Evaluation part of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/11/2014 03:00:47 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "header/loli.h" 20 | 21 | loliObj* lookupList(loliObj* lst, loliObj* env); 22 | 23 | loliObj* eval(loliObj* obj, loliObj* env){ 24 | // std::cout<type!=CONS){ 28 | // push(tmp); 29 | // }else{ 30 | // push(head(tmp)); 31 | // } 32 | // } 33 | // reverseStack(); 34 | // printStack(); 35 | if(nilp(obj)){ 36 | return nil; 37 | }else{ 38 | //obj->env = env; 39 | switch(obj->type){ 40 | case INT: 41 | case FLT: 42 | return obj; 43 | case CONS: 44 | if(equals(head(obj), quote)){ 45 | return obj; 46 | }else if(equals(head(obj), lambda)){ 47 | return mklambda(obj); 48 | }else if(equals(head(obj), set)){ 49 | return prim_set(obj, env); 50 | }else if(head(obj)->type == LAMBDA){ 51 | return apply(head(obj), lookupList(tail(obj), env), env); 52 | }else if(head(obj)->type == CONS){ 53 | return eval(cons(eval(head(obj), env), tail(obj)), env); 54 | }else if(equals(head(obj), ldef)){ 55 | if(nilp(getType(head(tail(obj))->type, head(obj), env))){ 56 | *env = *addToEnv(env, cons(head(tail(obj)), eval(head(tail(tail(obj))), env))); 57 | return head(tail(obj)); 58 | }else{ 59 | return mksym("Variable already exist!"); 60 | } 61 | }else if(equals(head(obj), lif)){ 62 | return prim_if(obj, env); 63 | }else if(equals(head(obj), llet)){ 64 | return prim_let(obj, env); 65 | } 66 | if(!nilp(getType(PROC, head(obj), env))){ 67 | return apply(getType(PROC, head(obj), env), lookupList(tail(obj), env), env); 68 | }else{ 69 | return apply(getType(LAMBDA, head(obj), env), lookupList(tail(obj), env), env); 70 | } 71 | case SYM: 72 | if(nilp(lookup(obj, env))){ 73 | return mksym("Symbol Unbound!"); 74 | }else{ 75 | // return eval(tail(head(lookup(obj, env))), env); 76 | return tail(head(lookup(obj, env))); 77 | } 78 | case CHAR: 79 | case STRING: 80 | case PROC: 81 | case LAMBDA: 82 | return obj; 83 | default: 84 | return nil; 85 | } 86 | } 87 | } 88 | 89 | loliObj* lookupList(loliObj* lst, loliObj* env){ 90 | if(nilp(lst)){ 91 | return nil; 92 | }else{ 93 | // if(head(lst)->type != SYM){ 94 | return cons(eval(head(lst), env), lookupList(tail(lst), env)); 95 | // }else{ 96 | // return cons(eval(tail(head(lookup(head(lst), env))), env), lookupList(tail(lst), env)); 97 | // } 98 | } 99 | return nil; 100 | } 101 | -------------------------------------------------------------------------------- /src/LoLi/loli_file.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_file.cpp 5 | * 6 | * Description: File Reader of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/04/2014 07:32:54 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "header/loli.h" 24 | 25 | bool readFile(std::string fileName, loliObj* env){ 26 | std::ifstream file(fileName); 27 | if(!file){ 28 | std::cout<<"Fail to read file!"< 20 | 21 | int guitest(int argc, char *argv[]){ 22 | GtkWidget *window; 23 | gtk_init(&argc, &argv); 24 | window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 25 | gtk_window_set_default_size(GTK_WINDOW(window), 300, 200); 26 | g_signal_connect(GTK_WIDGET(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); 27 | gtk_widget_show(window); 28 | gtk_main(); 29 | return(0); 30 | } 31 | 32 | int realgui(int argc, char *argv[]){ 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/LoLi/loli_gui.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | False 7 | 8 | 9 | 10 | True 11 | False 12 | vertical 13 | 2 14 | 15 | 16 | True 17 | False 18 | 19 | 20 | True 21 | False 22 | _File 23 | True 24 | 25 | 26 | True 27 | False 28 | 29 | 30 | gtk-new 31 | True 32 | False 33 | True 34 | True 35 | 36 | 37 | 38 | 39 | gtk-open 40 | True 41 | False 42 | True 43 | True 44 | 45 | 46 | 47 | 48 | gtk-save 49 | True 50 | False 51 | True 52 | True 53 | 54 | 55 | 56 | 57 | gtk-save-as 58 | True 59 | False 60 | True 61 | True 62 | 63 | 64 | 65 | 66 | True 67 | False 68 | 69 | 70 | 71 | 72 | gtk-quit 73 | True 74 | False 75 | True 76 | True 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | True 86 | False 87 | _Edit 88 | True 89 | 90 | 91 | True 92 | False 93 | 94 | 95 | gtk-cut 96 | True 97 | False 98 | True 99 | True 100 | 101 | 102 | 103 | 104 | gtk-copy 105 | True 106 | False 107 | True 108 | True 109 | 110 | 111 | 112 | 113 | gtk-paste 114 | True 115 | False 116 | True 117 | True 118 | 119 | 120 | 121 | 122 | gtk-delete 123 | True 124 | False 125 | True 126 | True 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | True 136 | False 137 | _View 138 | True 139 | 140 | 141 | 142 | 143 | True 144 | False 145 | _Help 146 | True 147 | 148 | 149 | True 150 | False 151 | 152 | 153 | gtk-about 154 | True 155 | False 156 | True 157 | True 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | False 167 | True 168 | 0 169 | 170 | 171 | 172 | 173 | True 174 | False 175 | icons 176 | 2 177 | 178 | 179 | False 180 | True 181 | 1 182 | 183 | 184 | 185 | 186 | True 187 | True 188 | 189 | 190 | False 191 | True 192 | 2 193 | 194 | 195 | 196 | 197 | True 198 | True 199 | 200 | 201 | False 202 | True 203 | 3 204 | 205 | 206 | 207 | 208 | True 209 | False 210 | 10 211 | 10 212 | 10 213 | 10 214 | 6 215 | 6 216 | 2 217 | 218 | 219 | False 220 | True 221 | end 222 | 4 223 | 224 | 225 | 226 | 227 | 228 | 229 | -------------------------------------------------------------------------------- /src/LoLi/loli_lambda.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_lambda.cpp 5 | * 6 | * Description: Lambda of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/02/2014 09:20:41 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include 20 | 21 | #include "header/loli.h" 22 | #include "header/loli_gc.h" 23 | 24 | loliObj* mklambda(loliObj* exp){ 25 | exp = tail(exp); 26 | loliObj *tmp = new (UseGC) loliObj(LAMBDA); 27 | tmp->type = LAMBDA; 28 | tmp->env = head(exp); 29 | // tmp->head = head(tail(exp)); //using head as the Type def 30 | tmp->tail = head(tail(exp)); //using tail as the Expression 31 | return tmp; 32 | } 33 | -------------------------------------------------------------------------------- /src/LoLi/loli_let.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_let.cpp 5 | * 6 | * Description: Let of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/16/2014 09:04:51 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "header/loli.h" 20 | 21 | #include 22 | 23 | loliObj* prim_let(loliObj* exp, loliObj* env){ 24 | /* 25 | * (let ((SYM VAL) 26 | * (SYM VAL) 27 | * ...) 28 | * (EXP)) 29 | */ 30 | exp = tail(exp); 31 | // std::cout< 19 | 20 | #include "header/loli.h" 21 | 22 | int int_length(loliObj* lst){ 23 | if(nilp(lst)){ 24 | return 0; 25 | }else{ 26 | return 1 + int_length(tail(lst)); 27 | } 28 | } 29 | 30 | loliObj* prim_length(loliObj* lst){ 31 | return mkint(int_length(lst)); 32 | } 33 | 34 | //Append[(a (b . nil))] -> (a .... (b .... . nil)) 35 | loliObj* prim_append(loliObj* lst){ 36 | if(nilp(head(lst))){ 37 | return tail(lst); 38 | } 39 | if(head(lst)->type != CONS){ 40 | std::cout<<"The first argument must be a CONS\n"; 41 | return nil; 42 | } 43 | return cons(head(head(lst)), cons(tail(head(lst)), tail(lst))); 44 | } 45 | 46 | loliObj* prim_list(loliObj* lst, loliObj* env){ 47 | return lst; 48 | } 49 | -------------------------------------------------------------------------------- /src/LoLi/loli_main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_main.cpp 5 | * 6 | * Description: The main part (aka. the entrance of LoLi) 7 | * 8 | * Version: 1.0 9 | * Created: 04/05/2014 01:45:34 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "header/loli.h" 24 | 25 | #define VERSION "developing alpha 2" 26 | 27 | void showHelp(); 28 | 29 | void loli_init_tl(){ 30 | // top_env = addToEnv(top_env, cons(mksym("a"), mkflt(10.0011011))); 31 | top_env = addToEnv(top_env, cons(t, t)); 32 | top_env = addToEnv(top_env, cons(nil, nil)); 33 | top_env = addToEnv(top_env, cons(quote, quote)); 34 | //top_env = addToEnv(top_env, cons(mksym("top_env"), top_env)); 35 | 36 | //Creating Primitive Operators 37 | loliObj* loli_sum = mkproc(proc_sum); 38 | loliObj* loli_mul = mkproc(proc_mul); 39 | loliObj* loli_sub = mkproc(proc_sub); 40 | loliObj* loli_div = mkproc(proc_div); 41 | loliObj* loli_add1 = mkproc(proc_add1); 42 | loliObj* loli_sub1 = mkproc(proc_sub1); 43 | loliObj* loli_mod = mkproc(proc_mod); 44 | loliObj* loli_greater = mkproc(proc_greater); 45 | loliObj* loli_lesser = mkproc(proc_lesser); 46 | loliObj* loli_exit = mkproc(proc_exit); 47 | loliObj* loli_cons = mkproc(prim_cons); 48 | loliObj* loli_atom = mkproc(proc_atom); 49 | loliObj* loli_head = mkproc(prim_head); 50 | loliObj* loli_tail = mkproc(prim_tail); 51 | loliObj* loli_eq = mkproc(prim_equals); 52 | loliObj* loli_get_cons = mkproc(get_cons); 53 | loliObj* loli_get_int= mkproc(get_int); 54 | loliObj* loli_get_flt = mkproc(get_flt); 55 | loliObj* loli_get_sym= mkproc(get_sym); 56 | loliObj* loli_get_proc = mkproc(get_proc); 57 | loliObj* loli_get_lambda= mkproc(get_lambda); 58 | loliObj* loli_list = mkproc(prim_list); 59 | 60 | top_env = addToEnv(top_env, cons(mksym("+"), loli_sum)); 61 | top_env = addToEnv(top_env, cons(mksym("*"), loli_mul)); 62 | top_env = addToEnv(top_env, cons(mksym("-"), loli_sub)); 63 | top_env = addToEnv(top_env, cons(mksym("/"), loli_div)); 64 | top_env = addToEnv(top_env, cons(mksym("add1"), loli_add1)); 65 | top_env = addToEnv(top_env, cons(mksym("sub1"), loli_sub1)); 66 | top_env = addToEnv(top_env, cons(mksym("mod"), loli_mod)); 67 | top_env = addToEnv(top_env, cons(mksym(">?"), loli_greater)); 68 | top_env = addToEnv(top_env, cons(mksym("= 2){ 95 | if(strcmp(argv[1] , "--eval") == 0){ 96 | std::cout< 20 | 21 | #include "header/loli.h" 22 | 23 | std::string toString(loliObj* obj){ 24 | switch(obj->type){ 25 | case INT: 26 | case FLT: 27 | case SYM: 28 | return obj->value; 29 | case CONS: 30 | // if(nilp(head(obj))){ 31 | // return "NIL"; 32 | // }else if(nilp(tail(obj))){ 33 | // return "(" + toString(head(obj)) + ")"; 34 | // }else{ 35 | if(head(obj) == quote){ 36 | return "'" + toString(head(tail(obj))); 37 | }else{ 38 | return "(" + toString(head(obj)) + " . " + toString(tail(obj)) + ")"; 39 | } 40 | case CHAR: 41 | case STRING: 42 | return obj->value; 43 | case PROC: 44 | return ""; 45 | case LAMBDA: 46 | return "env) + ">"; 47 | } 48 | return ""; 49 | } 50 | -------------------------------------------------------------------------------- /src/LoLi/loli_parser.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_parser.cpp 5 | * 6 | * Description: Parser of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/14/2014 01:33:16 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include "header/loli.h" 23 | 24 | loliObj* parseList(std::string exp); 25 | 26 | loliObj* parse(std::string exp){ 27 | while(isspace(exp[0])){ 28 | exp = exp.substr(1); 29 | } 30 | if(exp[0] == '\0'){ 31 | return nil; 32 | } 33 | if(exp[0] == '('){ 34 | // std::cout< 21 | #include 22 | #include 23 | 24 | #include "header/loli.h" 25 | 26 | loliObj* proc_sum(loliObj* lst, loliObj* env){ 27 | double tmp = 0; 28 | for(loliObj* e = lst;!nilp(e);e = tail(e)){ 29 | if(head(e)->type == INT || (head(e)->type == FLT)){ 30 | tmp = tmp + std::stod(head(e)->value); 31 | } 32 | } 33 | if((int)tmp == tmp){ 34 | return mkint((int)tmp); 35 | } 36 | return mkflt(tmp); 37 | } 38 | 39 | loliObj* proc_mul(loliObj* lst, loliObj* env){ 40 | double tmp = 1; 41 | for(loliObj* e = lst;!nilp(e);e = tail(e)){ 42 | if(head(e)->type == INT || (head(e)->type == FLT)){ 43 | tmp = tmp * std::stod(head(e)->value); 44 | } 45 | } 46 | if((int)tmp == tmp){ 47 | return mkint((int)tmp); 48 | } 49 | return mkflt(tmp); 50 | } 51 | 52 | loliObj* proc_sub(loliObj* lst, loliObj* env){ 53 | while(true){ 54 | if(nilp(lst)){ 55 | return mkint(0); 56 | } 57 | if(head(lst)->type == INT || (head(lst)->type == FLT)){ 58 | break; 59 | } 60 | lst = tail(lst); 61 | } 62 | double tmp = std::stod(head(lst)->value); 63 | for(loliObj* e = tail(lst);!nilp(e);e = tail(e)){ 64 | if(head(e)->type == INT || (head(e)->type == FLT)){ 65 | tmp = tmp - std::stod(head(e)->value); 66 | } 67 | } 68 | if((int)tmp == tmp){ 69 | return mkint((int)tmp); 70 | } 71 | return mkflt(tmp); 72 | } 73 | 74 | loliObj* proc_div(loliObj* lst, loliObj* env){ 75 | while(true){ 76 | if(nilp(lst)){ 77 | return mkint(0); 78 | } 79 | if(head(lst)->type == INT || (head(lst)->type == FLT)){ 80 | break; 81 | } 82 | lst = tail(lst); 83 | } 84 | double tmp = std::stod(head(lst)->value); 85 | for(loliObj* e = tail(lst);!nilp(e);e = tail(e)){ 86 | if(head(e)->type == INT || (head(e)->type == FLT)){ 87 | if(std::stod(head(e)->value) != 0){ 88 | tmp = tmp / std::stod(head(e)->value); 89 | }else{ 90 | std::cout<<"\nWarnning: Cannot be ZERO, ignored\n"; 91 | } 92 | } 93 | } 94 | if((int)tmp == tmp){ 95 | return mkint((int)tmp); 96 | } 97 | return mkflt(tmp); 98 | } 99 | 100 | loliObj* proc_add1(loliObj* num, loliObj* env){ 101 | double tmp; 102 | try{ 103 | tmp = std::stod(head(num)->value) + 1; 104 | }catch(...){ 105 | std::cout<value) - 1; 118 | }catch(...){ 119 | std::cout<type == INT || (head(lst)->type == FLT)){ 134 | break; 135 | } 136 | lst = tail(lst); 137 | } 138 | double tmp = std::stod(head(lst)->value); 139 | for(loliObj* e = tail(lst);!nilp(e);e = tail(e)){ 140 | if(head(e)->type == INT || (head(e)->type == FLT)){ 141 | if(std::stod(head(e)->value) != 0){ 142 | tmp = fmod(tmp, std::stod(head(e)->value)); 143 | }else{ 144 | std::cout<<"\nWarnning: Cannot be ZERO, ignored\n"; 145 | } 146 | } 147 | } 148 | if((int)tmp == tmp){ 149 | return mkint((int)tmp); 150 | } 151 | return mkflt(tmp); 152 | } 153 | 154 | loliObj* proc_greater(loliObj* lst, loliObj* env){ 155 | while(true){ 156 | if(nilp(lst)){ 157 | return mkint(0); 158 | } 159 | if(head(lst)->type == INT || (head(lst)->type == FLT)){ 160 | break; 161 | } 162 | lst = tail(lst); 163 | } 164 | double tmp = std::stod(head(lst)->value); 165 | for(loliObj* e = tail(lst);!nilp(e);e = tail(e)){ 166 | if(head(e)->type == INT || (head(e)->type == FLT)){ 167 | if(tmp <= std::stod(head(e)->value)){ 168 | return nil; 169 | } 170 | } 171 | } 172 | return t; 173 | } 174 | 175 | loliObj* proc_lesser(loliObj* lst, loliObj* env){ 176 | while(true){ 177 | if(nilp(lst)){ 178 | return mkint(0); 179 | } 180 | if(head(lst)->type == INT || (head(lst)->type == FLT)){ 181 | break; 182 | } 183 | lst = tail(lst); 184 | } 185 | double tmp = std::stod(head(lst)->value); 186 | for(loliObj* e = tail(lst);!nilp(e);e = tail(e)){ 187 | if(head(e)->type == INT || (head(e)->type == FLT)){ 188 | if(tmp >= std::stod(head(e)->value)){ 189 | return nil; 190 | } 191 | } 192 | } 193 | return t; 194 | } 195 | 196 | loliObj* proc_exit(loliObj* dum, loliObj* env){ 197 | //Dummy input, do nothing 198 | exit(0); 199 | } 200 | 201 | loliObj* proc_atom(loliObj* obj, loliObj* env){ 202 | if(head(obj)->type == CONS){ 203 | return nil; 204 | }else{ 205 | return t; 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /src/LoLi/loli_read.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_read.cpp 5 | * 6 | * Description: Read and pair module of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/11/2014 02:43:34 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "header/loli.h" 24 | 25 | std::string readPaired(int i, bool quote){ // i indicates the parentheses balance couting, quote indicated wheather between " or not 26 | std::string tmp; 27 | std::getline(std::cin, tmp); 28 | int p = i; 29 | bool q = quote; 30 | for(ulong j = 0; j < tmp.length(); j++){ 31 | if(tmp[j] == ';'){ 32 | tmp = tmp.substr(0, j); 33 | break; 34 | } 35 | if(tmp[j] == '"'){ 36 | q = !q; 37 | } 38 | if(tmp[j] == '('){ 39 | if(!q) 40 | p = p + 1; 41 | }else if(tmp[j] == ')'){ 42 | if(!q) 43 | p = p - 1; 44 | } 45 | if(p < 0){ 46 | std::cout<<"Warning! Extra ) found that cannot pair up, ignored and returned"< 21 | #include 22 | #include 23 | 24 | #include "header/loli.h" 25 | 26 | void repl(loliObj* env){ 27 | std::cout << "LoLi > "; 28 | std::string input; 29 | input = readPaired(0, false); 30 | if(input[0] == '\0'){ 31 | return; 32 | } 33 | std::cout< 22 | 23 | loliObj* prim_set(loliObj* exp, loliObj* env){ //(set! obj val) 24 | exp = tail(exp); 25 | if(nilp(getType(head(tail(exp))->type, head(exp), env))){ 26 | return mksym("Symbol not defined!"); 27 | }else{ 28 | *getType(head(tail(exp))->type, head(exp), env) = *eval(head(tail(exp)), env); 29 | return exp; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/LoLi/loli_stack.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_stack.cpp 5 | * 6 | * Description: Stack of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/19/2014 11:06:09 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "header/loli.h" 20 | #include "header/loli_gc.h" 21 | 22 | #include 23 | 24 | #define STACKS 100 25 | 26 | loliObj loli_stack[STACKS]; 27 | int obj_in_stack = 0; 28 | 29 | bool isStackEmpty(){ 30 | return obj_in_stack == 0; 31 | } 32 | 33 | bool isStackFull(){ 34 | return obj_in_stack == STACKS; 35 | } 36 | 37 | void printStack(){ 38 | for(int i = 0; i < obj_in_stack; i++){ 39 | std::cout<<"Stack["<< i + 1 <<"] : " << toString(&loli_stack[i])< 0; i--){ 66 | tmp[obj_in_stack - i] = loli_stack[i - 1]; 67 | } 68 | for(int i = 0; i < obj_in_stack; i++){ 69 | loli_stack[i] = tmp[i]; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/LoLi/loli_symbols.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_symbols.cpp 5 | * 6 | * Description: The Internal Symbols of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/05/2014 01:23:47 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "header/loli.h" 20 | 21 | loliObj* nil = mksym("nil"); 22 | loliObj* t = mksym("t"); 23 | loliObj* lambda = mksym("\\"); 24 | loliObj* set = mksym("set!"); 25 | loliObj* quote = mksym("quote"); 26 | loliObj* anon = mksym("_"); 27 | loliObj* ldef = mksym("def"); 28 | loliObj* lif = mksym("if"); 29 | loliObj* llet = mksym("let"); 30 | 31 | bool nilp(loliObj* o){ 32 | if(o->type == SYM && o->value == "nil"){ 33 | return true; 34 | } 35 | return false; 36 | } 37 | -------------------------------------------------------------------------------- /src/LoLi/loli_types.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_types.cpp 5 | * 6 | * Description: The Type System of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 04/04/2014 07:15:57 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "header/loli.h" 24 | #include "header/loli_gc.h" 25 | 26 | loliObj* mksym(std::string symName){ 27 | loliObj *tmp = new (UseGC) loliObj(SYM); 28 | tmp->value = symName; 29 | return tmp; 30 | } 31 | 32 | loliObj* mkint(int number){ 33 | loliObj *tmp = new (UseGC) loliObj(INT); 34 | tmp->value = std::to_string(number); 35 | return tmp; 36 | } 37 | 38 | loliObj* mkflt(long double number){ 39 | loliObj *tmp = new (UseGC) loliObj(FLT); 40 | std::stringstream ss; 41 | ss << number; 42 | std::string n; 43 | ss >> n; 44 | tmp->value = n; 45 | //tmp->value = std::to_string(number); 46 | return tmp; 47 | } 48 | 49 | loliObj* mkproc(loliObj::procedure &proc){ 50 | loliObj *tmp = new (UseGC)loliObj(PROC); 51 | tmp->proc = proc; 52 | return tmp; 53 | } 54 | 55 | bool equals(loliObj* a, loliObj* b){ 56 | if((a->type == b->type) && (a->value == b->value)){ 57 | return true; 58 | } 59 | return false; 60 | } 61 | 62 | loliObj* prim_equals(loliObj* obj, loliObj* env){ 63 | if(equals(head(obj), head(tail(obj)))){ 64 | return t; 65 | }else{ 66 | return nil; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/LoLi2/.sln: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LoLi-Lang/LoLi/9306a531a42df9e81b75de4bc278aa8dc9c22a3f/src/LoLi2/.sln -------------------------------------------------------------------------------- /src/LoLi2/.ycm_extra_conf.py: -------------------------------------------------------------------------------- 1 | # This file is NOT licensed under the GPLv3, which is the license for the rest 2 | # of YouCompleteMe. 3 | # 4 | # Here's the license text for this file: 5 | # 6 | # This is free and unencumbered software released into the public domain. 7 | # 8 | # Anyone is free to copy, modify, publish, use, compile, sell, or 9 | # distribute this software, either in source code form or as a compiled 10 | # binary, for any purpose, commercial or non-commercial, and by any 11 | # means. 12 | # 13 | # In jurisdictions that recognize copyright laws, the author or authors 14 | # of this software dedicate any and all copyright interest in the 15 | # software to the public domain. We make this dedication for the benefit 16 | # of the public at large and to the detriment of our heirs and 17 | # successors. We intend this dedication to be an overt act of 18 | # relinquishment in perpetuity of all present and future rights to this 19 | # software under copyright law. 20 | # 21 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24 | # IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 25 | # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 26 | # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27 | # OTHER DEALINGS IN THE SOFTWARE. 28 | # 29 | # For more information, please refer to 30 | 31 | import os 32 | import ycm_core 33 | 34 | # These are the compilation flags that will be used in case there's no 35 | # compilation database set (by default, one is not set). 36 | # CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR. 37 | flags = [ 38 | '-Wall', 39 | '-Wextra', 40 | '-Werror', 41 | # You 100% do NOT need -DUSE_CLANG_COMPLETER in your flags; only the YCM 42 | # source code needs it. 43 | '-DUSE_CLANG_COMPLETER', 44 | # THIS IS IMPORTANT! Without a "-std=" flag, clang won't know which 45 | # language to use when compiling headers. So it will guess. Badly. So C++ 46 | # headers will be compiled as C headers. You don't want that so ALWAYS specify 47 | # a "-std=". 48 | # For a C project, you would set this to something like 'c99' instead of 49 | # 'c++11'. 50 | '-std=c++11', 51 | # ...and the same thing goes for the magic -x option which specifies the 52 | # language that the files to be compiled are written in. This is mostly 53 | # relevant for c++ headers. 54 | # For a C project, you would set this to 'c' instead of 'c++'. 55 | '-x', 56 | 'c++', 57 | '-isystem', 58 | '../BoostParts', 59 | '-isystem', 60 | # This path will only work on OS X, but extra paths that don't exist are not 61 | # harmful 62 | '-I', 63 | '.', 64 | '-I', 65 | '../gc/include', 66 | '-L', 67 | '../gc/build -lgc' 68 | '-isystem', 69 | '/usr/include', 70 | '-isystem', 71 | '/usr/local/include', 72 | ] 73 | 74 | 75 | # Set this to the absolute path to the folder (NOT the file!) containing the 76 | # compile_commands.json file to use that instead of 'flags'. See here for 77 | # more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html 78 | # 79 | # Most projects will NOT need to set this to anything; you can just change the 80 | # 'flags' list of compilation flags. Notice that YCM itself uses that approach. 81 | compilation_database_folder = '' 82 | 83 | if os.path.exists( compilation_database_folder ): 84 | database = ycm_core.CompilationDatabase( compilation_database_folder ) 85 | else: 86 | database = None 87 | 88 | SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ] 89 | 90 | def DirectoryOfThisScript(): 91 | return os.path.dirname( os.path.abspath( __file__ ) ) 92 | 93 | 94 | def MakeRelativePathsInFlagsAbsolute( flags, working_directory ): 95 | if not working_directory: 96 | return list( flags ) 97 | new_flags = [] 98 | make_next_absolute = False 99 | path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] 100 | for flag in flags: 101 | new_flag = flag 102 | 103 | if make_next_absolute: 104 | make_next_absolute = False 105 | if not flag.startswith( '/' ): 106 | new_flag = os.path.join( working_directory, flag ) 107 | 108 | for path_flag in path_flags: 109 | if flag == path_flag: 110 | make_next_absolute = True 111 | break 112 | 113 | if flag.startswith( path_flag ): 114 | path = flag[ len( path_flag ): ] 115 | new_flag = path_flag + os.path.join( working_directory, path ) 116 | break 117 | 118 | if new_flag: 119 | new_flags.append( new_flag ) 120 | return new_flags 121 | 122 | 123 | def IsHeaderFile( filename ): 124 | extension = os.path.splitext( filename )[ 1 ] 125 | return extension in [ '.h', '.hxx', '.hpp', '.hh' ] 126 | 127 | 128 | def GetCompilationInfoForFile( filename ): 129 | # The compilation_commands.json file generated by CMake does not have entries 130 | # for header files. So we do our best by asking the db for flags for a 131 | # corresponding source file, if any. If one exists, the flags for that file 132 | # should be good enough. 133 | if IsHeaderFile( filename ): 134 | basename = os.path.splitext( filename )[ 0 ] 135 | for extension in SOURCE_EXTENSIONS: 136 | replacement_file = basename + extension 137 | if os.path.exists( replacement_file ): 138 | compilation_info = database.GetCompilationInfoForFile( 139 | replacement_file ) 140 | if compilation_info.compiler_flags_: 141 | return compilation_info 142 | return None 143 | return database.GetCompilationInfoForFile( filename ) 144 | 145 | 146 | def FlagsForFile( filename, **kwargs ): 147 | if database: 148 | # Bear in mind that compilation_info.compiler_flags_ does NOT return a 149 | # python list, but a "list-like" StringVec object 150 | compilation_info = GetCompilationInfoForFile( filename ) 151 | if not compilation_info: 152 | return None 153 | 154 | final_flags = MakeRelativePathsInFlagsAbsolute( 155 | compilation_info.compiler_flags_, 156 | compilation_info.compiler_working_dir_ ) 157 | 158 | # NOTE: This is just for YouCompleteMe; it's highly likely that your project 159 | # does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR 160 | # ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT. 161 | try: 162 | final_flags.remove( '-stdlib=libc++' ) 163 | except ValueError: 164 | pass 165 | else: 166 | relative_to = DirectoryOfThisScript() 167 | final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) 168 | 169 | return { 170 | 'flags': final_flags, 171 | 'do_cache': True 172 | } 173 | -------------------------------------------------------------------------------- /src/LoLi2/.ycm_extra_conf.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LoLi-Lang/LoLi/9306a531a42df9e81b75de4bc278aa8dc9c22a3f/src/LoLi2/.ycm_extra_conf.pyc -------------------------------------------------------------------------------- /src/LoLi2/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | CLANG = clang++ 3 | CFLAGSG = -std=c++11 -stdlib=libstdc++ -Wall -Og -Wextra -g 4 | CFLAGSC = -std=c++11 -stdlib=libstdc++ -Wall -O0 -Wextra -g 5 | 6 | HEADERS = \ 7 | include/loli_obj.h\ 8 | include/loli_util.h\ 9 | include/loli_eval.h\ 10 | include/loli_env.h\ 11 | include/loli_stack.h\ 12 | include/loli_typeclass.h\ 13 | include/loli_apply.h\ 14 | include/loli_lambda.h\ 15 | include/loli_prim.h\ 16 | include/loli_parser.h\ 17 | include/loli_repl.h\ 18 | include/loli_reader.h 19 | 20 | MAIN = \ 21 | loli_obj.cpp\ 22 | loli_stack.cpp\ 23 | loli_reader.cpp\ 24 | loli_parser.cpp\ 25 | loli_util.cpp\ 26 | loli_env.cpp\ 27 | loli_eval.cpp\ 28 | loli_apply.cpp\ 29 | loli_repl.cpp\ 30 | loli_typeclass.cpp\ 31 | loli_main.cpp 32 | 33 | TEST = \ 34 | loli_obj.cpp\ 35 | loli_util.cpp\ 36 | loli_reader.cpp\ 37 | loli_prim.cpp\ 38 | loli_apply.cpp\ 39 | loli_eval.cpp\ 40 | loli_lambda.cpp\ 41 | loli_env.cpp\ 42 | loli_typeclass.cpp\ 43 | loli_stack.cpp\ 44 | loli_parser.cpp\ 45 | loli2test.cpp 46 | 47 | CURRENTG: 48 | $(CC) $(CFLAGSG) -o currentg $(MAIN) 49 | 50 | CURRENTC: 51 | $(CLANG) $(CFLAGSC) -o currentc $(MAIN) 52 | 53 | TEST: $(HEADERS) 54 | $(CLANG) $(CFLAGSC) $(GCINCLUDE) $(GC) -o test $(TEST) 55 | 56 | .PHONY: clean 57 | clean: 58 | rm *~ 59 | -------------------------------------------------------------------------------- /src/LoLi2/README.mkd: -------------------------------------------------------------------------------- 1 | LoLi 2 2 | ====== 3 | 4 | LoLi 2 is the more advanced version of LoLi. 5 | 6 | Unlike LoLi (the prototype version), there will be a stack and AST in LoLi 2. 7 | 8 | Why LoLi 2 9 | ---------- 10 | Since there are some design faults in LoLi, I decided to start from blank again. 11 | 12 | Differences from LoLi 13 | --------------------- 14 | 15 | There will be a stack and AST in LoLi 2 as mentioned above, also, the LoLi compiler will be designed and developed for this version. 16 | 17 | Also, because of the limitation of LoLi, the CBMI system may not work well with it. But LoLi 2 will be designed against CBMI. 18 | -------------------------------------------------------------------------------- /src/LoLi2/currentc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LoLi-Lang/LoLi/9306a531a42df9e81b75de4bc278aa8dc9c22a3f/src/LoLi2/currentc -------------------------------------------------------------------------------- /src/LoLi2/include/loli_apply.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_apply.h 5 | * 6 | * Description: Apply of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 08/17/2014 08:24:22 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_APPLY_ 20 | #define __LOLI_APPLY_ 21 | 22 | #include "loli_obj.h" 23 | 24 | extern loliObj* c_apply(loliObj* fn, loliObj* arg, loliObj* env); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/LoLi2/include/loli_env.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_env.h 5 | * 6 | * Description: Env of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 07/17/2014 01:15:09 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_ENV_ 20 | #define __LOLI_ENV_ 21 | 22 | #include "loli_obj.h" 23 | #include "loli_typeclass.h" 24 | 25 | extern loliCons* top_env; 26 | 27 | extern loliCons* to_env_entry(loliObj* sym, loliObj* value); 28 | extern loliCons* add_to_env(loliObj* obj, loliObj* env); 29 | extern loliObj* add_to_top_env(loliObj* obj); 30 | extern loliObj* lookup_env(loliObj* sym, loliObj* env); 31 | extern loliObj* lookup_top_env(loliObj* sym); 32 | extern loliObj* get_type(loliTypeClass* type, loliObj* sym, loliObj* env); 33 | 34 | //Primitive functions: 35 | extern loliObj* c_def(loliObj* obj); 36 | extern loliObj* c_set(loliObj* obj); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/LoLi2/include/loli_eval.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_eval.h 5 | * 6 | * Description: Eval of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 07/22/2014 03:25:29 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_EVAL_ 20 | #define __LOLI_EVAL_ 21 | 22 | #include "loli_obj.h" 23 | 24 | extern loliObj* eval_list(loliObj* lst); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/LoLi2/include/loli_lambda.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_lambda.h 5 | * 6 | * Description: Lambda of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 09/26/2014 03:49:44 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_LAMBDA_ 20 | #define __LOLI_LAMBDA_ 21 | 22 | #include "loli_obj.h" 23 | 24 | loliObj* c_lambda(loliObj* e); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/LoLi2/include/loli_obj.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_obj.h 5 | * 6 | * Description: Object of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/26/2014 10:09:32 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_OBJ_ 20 | #define __LOLI_OBJ_ 21 | 22 | #include "loli_typeclass.h" 23 | #include 24 | #include 25 | #include 26 | 27 | //Macros 28 | #define lnum(x) ((loliNum*)x) 29 | #define lint(x) ((loliInt*)x) 30 | #define lflt(x) ((loliFlt*)x) 31 | #define lchar(x) ((loliChar*)x) 32 | #define lstr(x) ((loliString*)x) 33 | #define lcons(x) ((loliCons*)x) 34 | #define lfunc(x) ((loliFunction*)x) 35 | #define lproc(x) ((loliPrim*)x) 36 | #define llambda(x) ((loliLambda*)x) 37 | #define lsym(x) ((loliSym*)x) 38 | #define lkey(x) ((loliKey*)x) 39 | #define lbool(x) ((loliBool*)x) 40 | 41 | #define INT(x) new loliInt(x) 42 | #define FLT(x) new loliFlt(x) 43 | #define SYM(x) new loliSym(x) 44 | #define KEY(x) new loliKey(x) 45 | #define CHAR(x) new loliChar(x) 46 | #define STRING(x) new loliString(x) 47 | #define sCONS(x) new loliCons(x) //Single Cons 48 | #define CONS(x, y) new loliCons(x, y) 49 | #define PROC(x, y, z) new loliPrim(x, y, z) 50 | #define LAMBDA(x, y, z) new loliLambda(x, y, z) 51 | 52 | class loliObj; 53 | 54 | extern loliObj* nil; 55 | extern loliObj* t; 56 | extern loliObj* quote; 57 | 58 | extern loliObj* boolt; 59 | extern loliObj* boolf; 60 | 61 | class loliObj { 62 | public: 63 | typedef loliObj* (loliProc)(loliObj*); 64 | loliTypeClass *type; 65 | loliObj* env; 66 | virtual std::string toString(){return "";} 67 | virtual int length(){return 1;} 68 | virtual loliObj* eval(loliObj* env){ 69 | //For debug: 70 | std::cout<toString()<type; 78 | } 79 | bool nilp(){ 80 | return this->equal(nil); 81 | } 82 | 83 | loliObj(){ 84 | this->type = typeOBJ; 85 | env = nil; 86 | }; 87 | }; 88 | 89 | class loliNum : public loliObj { //Place holder 90 | public: 91 | loliTypeClass *type = typeNUM; 92 | 93 | virtual long double getValue(){return 0;} 94 | 95 | int length(){ 96 | return 1; 97 | } 98 | 99 | loliObj* eval(loliObj* env) override { 100 | this->type = typeNUM; 101 | std::cout<value; 113 | } 114 | 115 | std::string toString(){ 116 | return std::to_string(value); 117 | } 118 | 119 | loliInt(long int n){ 120 | this->type = typeINT; 121 | value = n; 122 | } 123 | 124 | loliObj* eval(loliObj* env){ 125 | this->type = typeINT; 126 | std::cout<toString()<value == this->value; 136 | } 137 | }; 138 | 139 | class loliFlt: public loliNum { 140 | public: 141 | long double value; 142 | loliTypeClass *type = typeFLT; 143 | 144 | long double getValue(){ 145 | return this->value; 146 | } 147 | 148 | std::string toString(){ 149 | return std::to_string(value); 150 | } 151 | 152 | loliFlt(long double n){ 153 | this->type = typeFLT; 154 | value = n; 155 | } 156 | 157 | loliObj* eval(loliObj* env){ 158 | this->type = typeFLT; 159 | std::cout<getType()->toString()<value == this->value; 168 | } 169 | }; 170 | 171 | class loliSym: public loliObj { 172 | public: 173 | std::string name = ""; 174 | loliTypeClass *type = typeSYM; 175 | 176 | std::string toString(){ 177 | return name; 178 | } 179 | 180 | loliSym(){} 181 | 182 | loliSym(std::string v){ 183 | this->type = typeSYM; 184 | name = v; 185 | } 186 | 187 | bool equal(loliObj* o){ 188 | return lsym(o)->name == this->name; 189 | } 190 | 191 | int length(){ 192 | return 1; 193 | } 194 | 195 | loliObj* eval(loliObj* env); 196 | }; 197 | 198 | class loliKey: public loliObj { 199 | public: 200 | std::string name = ""; 201 | loliTypeClass *type = typeKEY; 202 | 203 | std::string toString(){ 204 | return ":" + name; 205 | } 206 | 207 | loliKey(){} 208 | 209 | loliKey(std::string v){ 210 | this->type = typeKEY; 211 | name = v; 212 | } 213 | 214 | bool equal(loliObj* o){ 215 | return ((loliKey*)o)->name == this->name; 216 | } 217 | 218 | int length(){ 219 | return 1; 220 | } 221 | 222 | loliObj* eval(loliObj* env) override { 223 | std::cout<<"Override\n"; 224 | this->type = typeKEY; 225 | std::cout<getType()->toString()<toString(); 238 | if(tl->type != typeCONS){ 239 | return tmp + " . " + tl->toString() + ")"; 240 | }else{ 241 | return tmp + " " + tl->toString() + ")"; 242 | } 243 | return ""; //Blank 244 | } 245 | 246 | int length(){ 247 | return 1 + tl->length(); 248 | } 249 | 250 | loliCons(){ 251 | this->type = typeCONS; 252 | hd = nil; 253 | tl = nil; 254 | } 255 | 256 | loliCons(loliObj* obj){ 257 | this->type = typeCONS; 258 | hd = obj; 259 | tl = nil; 260 | } 261 | 262 | loliCons(loliObj* hd, loliObj* tl){ 263 | this->type = typeCONS; 264 | this->hd = hd; 265 | this->tl = tl; 266 | } 267 | 268 | void setHead(loliObj* o){ 269 | hd = o; 270 | } 271 | 272 | void setTail(loliObj* o){ 273 | tl = o; 274 | } 275 | 276 | loliObj* head(){ 277 | return hd; 278 | } 279 | 280 | loliObj* tail(){ 281 | return tl; 282 | } 283 | 284 | bool equal(loliObj* o){ 285 | return (this->hd->equal(((loliCons* )o)->hd)) && (this->tl->equal(((loliCons*)o)->tl)); 286 | } 287 | 288 | loliObj* eval(loliObj* env); 289 | }; 290 | 291 | class loliFunction: public loliObj { //Place Holder 292 | public: 293 | loliTypeClass *type = typeFN; 294 | 295 | loliObj* rtype; 296 | 297 | int length(){ 298 | return 1; 299 | } 300 | 301 | loliFunction(){} 302 | 303 | loliObj* eval(loliObj* env){ 304 | this->type = typeFN; 305 | std::cout<type->toString()<toString() + " >"; 318 | } 319 | 320 | loliPrim(){} 321 | 322 | loliPrim(loliObj::loliProc* p, loliObj* r, loliObj* i){ 323 | this->type = typePROC; 324 | this->proc = p; 325 | this->rtype = r; 326 | this->itype = i; 327 | } 328 | }; 329 | 330 | class loliLambda: public loliFunction { 331 | public: 332 | loliTypeClass *type = typeLAMBDA; 333 | loliObj* arg; 334 | loliObj* exp; 335 | 336 | std::string toString(){ 337 | return "arg->toString() + " -> " + this->rtype->toString() + " >"; 338 | } 339 | 340 | loliLambda(){} 341 | 342 | loliLambda(loliObj* r, loliObj* a, loliObj* e){ 343 | this->type = typeLAMBDA; 344 | this->rtype = r; 345 | this->arg = a; 346 | this->exp = e; 347 | } 348 | }; 349 | 350 | class loliChar: public loliObj { 351 | public: 352 | loliTypeClass *type = typeCHAR; 353 | 354 | char value; 355 | 356 | loliChar(){} 357 | 358 | loliChar(char c){ 359 | this->type = typeCHAR; 360 | this->value = c; 361 | } 362 | 363 | std::string toString(){ 364 | return "#\\" + std::to_string(value); 365 | } 366 | 367 | int length(){ 368 | return 1; 369 | } 370 | 371 | loliObj* eval(loliObj* env){ 372 | this->type = typeCHAR; 373 | std::cout<type->toString()<type = typeSTRING; 387 | this->value = str; 388 | } 389 | 390 | std::string toString(){ 391 | return value; 392 | } 393 | 394 | int length(){ 395 | return value.length(); 396 | } 397 | 398 | loliObj* eval(loliObj* env){ 399 | this->type = typeSTRING; 400 | std::cout<type->toString()<type = typeBOOL; 414 | this->value = b; 415 | if(b){ 416 | this->name = "true"; 417 | }else{ 418 | this->name = "false"; 419 | } 420 | } 421 | }; 422 | 423 | #endif 424 | -------------------------------------------------------------------------------- /src/LoLi2/include/loli_parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_parser.h 5 | * 6 | * Description: Parser of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 07/17/2014 11:12:19 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_PARSER_ 20 | #define __LOLI_PARSER_ 21 | 22 | #include 23 | #include "loli_obj.h" 24 | 25 | extern loliObj* parse_string(std::string str, loliObj* env); 26 | extern loliObj* parse_list(std::string str, loliObj* env); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/LoLi2/include/loli_prim.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_prim.cpp 5 | * 6 | * Description: Prim of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 08/17/2014 08:20:39 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_PRIM_ 20 | #define __LOLI_PRIM_ 21 | 22 | #include "loli_obj.h" 23 | 24 | extern loliObj* c_plus(loliObj* obj); 25 | extern loliObj* c_sub(loliObj* obj); 26 | extern loliObj* c_mult(loliObj* obj); 27 | extern loliObj* c_div(loliObj* obj); 28 | extern loliObj* c_quote(loliObj* obj); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/LoLi2/include/loli_reader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_reader.h 5 | * 6 | * Description: Reader of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/27/2014 04:11:03 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_READER_ 20 | #define __LOLI_READER_ 21 | 22 | #include 23 | #include 24 | 25 | extern std::string read_pair(int i, bool quote); 26 | extern std::string read_pair(); 27 | extern std::string read_pair(int i, bool quote, std::ifstream &stream); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/LoLi2/include/loli_repl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_repl.h 5 | * 6 | * Description: Repl of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 08/14/2014 03:14:20 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_REPL_ 20 | #define __LOLI_REPL_ 21 | 22 | #include "loli_obj.h" 23 | 24 | extern void c_repl(); 25 | extern void c_repl(loliObj* env); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/LoLi2/include/loli_stack.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_stack.cpp 5 | * 6 | * Description: Stack of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/26/2014 06:31:04 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_STACK_ 20 | #define __LOLI_STACK_ 21 | 22 | #include "loli_obj.h" 23 | #include "loli_util.h" 24 | 25 | #define STACK_SIZE 8192 26 | 27 | struct loliStack{ 28 | loliObj stack[STACK_SIZE]; 29 | int obj_in_stack; 30 | 31 | loliStack(){ 32 | obj_in_stack = 0; 33 | } 34 | 35 | bool isEmpty(){ 36 | return 0 == obj_in_stack; 37 | } 38 | 39 | bool isFull(){ 40 | return obj_in_stack == STACK_SIZE; 41 | } 42 | 43 | void push_obj(loliObj* o){ 44 | if(isFull()){ 45 | loli_err("Stack Overflow"); 46 | return; 47 | } 48 | stack[++obj_in_stack] = *o; 49 | } 50 | 51 | loliObj* pop_obj(){ 52 | if(isEmpty()){ 53 | loli_err("Stack Underflow"); 54 | return NULL; 55 | } 56 | return &stack[obj_in_stack--]; 57 | } 58 | }; 59 | 60 | extern loliStack global_stack; 61 | extern std::string stack_to_string(loliStack stack); 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/LoLi2/include/loli_type.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_type.h 5 | * 6 | * Description: Type of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 07/17/2014 01:45:54 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_TYPE_ 20 | #define __LOLI_TYPE_ 21 | 22 | #define is_int(obj) obj->type == INT 23 | #define is_flt(obj) obj->type == FLT 24 | #define is_sym(obj) obj->type == SYM 25 | #define is_proc(obj) obj->type == PROC 26 | #define is_cons(obj) obj->type == CONS 27 | #define is_lambda(obj) obj->type == LAMBDA 28 | #define is_char(obj) obj->type == CHAR 29 | #define is_str(obj) obj->type == CHAR 30 | #define is_bool(obj) obj->type == BOOL 31 | #define is_type(obj) obj->type == TYPE 32 | #define is_key(obj) obj->type == KEY 33 | 34 | #include "loli_obj.h" 35 | 36 | extern loliObj* c_is_int(loliObj* obj); 37 | extern loliObj* c_is_flt(loliObj* obj); 38 | extern loliObj* c_is_sym(loliObj* obj); 39 | extern loliObj* c_is_proc(loliObj* obj); 40 | extern loliObj* c_is_lambda(loliObj* obj); 41 | extern loliObj* c_is_char(loliObj* obj); 42 | extern loliObj* c_is_str(loliObj* obj); 43 | extern loliObj* c_is_cons(loliObj* obj); 44 | extern loliObj* c_is_num(loliObj* obj); 45 | extern loliObj* c_is_bool(loliObj* obj); 46 | extern loliObj* c_is_type(loliObj* obj); 47 | extern loliObj* c_is_obj(loliObj* obj); 48 | 49 | loliKey* to_key(std::string k){ 50 | return new loliKey(k); 51 | } 52 | loliObj* kint = to_key("INT"); 53 | loliObj* kflt = to_key("FLT"); 54 | loliObj* knum = to_key("NUM"); 55 | loliObj* ksym = to_key("SYM"); 56 | loliObj* kcons = to_key("CONS"); 57 | loliObj* kproc = to_key("PROC"); 58 | loliObj* klambda = to_key("LAMBDA"); 59 | loliObj* kchar = to_key("CHAR"); 60 | loliObj* kstr = to_key("STRING"); 61 | loliObj* kbool = to_key("BOOL"); 62 | loliObj* kkey = to_key("KEYWORD"); 63 | loliObj* kobj = to_key("_"); 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/LoLi2/include/loli_typeclass.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_typeclass.h 5 | * 6 | * Description: Typeclass of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 08/26/2014 06:32:20 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_TYPECLASS_ 20 | #define __LOLI_TYPECLASS_ 21 | 22 | #include "loli_obj.h" 23 | #include 24 | #include 25 | #include 26 | 27 | class loliTypeClass; 28 | 29 | extern loliTypeClass* typeOBJ; 30 | extern loliTypeClass* typeNUM; 31 | extern loliTypeClass* typeINT; 32 | extern loliTypeClass* typeFLT; 33 | extern loliTypeClass* typeSYM; 34 | extern loliTypeClass* typeKEY; 35 | extern loliTypeClass* typeCONS; 36 | extern loliTypeClass* typeFN; 37 | extern loliTypeClass* typePROC; 38 | extern loliTypeClass* typeLAMBDA; 39 | extern loliTypeClass* typeCHAR; 40 | extern loliTypeClass* typeSTRING; 41 | extern loliTypeClass* typeBOOL; 42 | 43 | class loliTypeClass { 44 | public: 45 | loliTypeClass * parentType = typeOBJ; 46 | std::string identifier = ""; 47 | const char* ti; 48 | 49 | const std::string toString(){ 50 | return ":" + identifier + "\t" + ti; 51 | } 52 | //Contructures: 53 | loliTypeClass(){ 54 | this->parentType = typeOBJ; 55 | this->identifier = ""; 56 | } 57 | 58 | loliTypeClass(std::string id){ 59 | this->parentType = typeOBJ; 60 | this->identifier = id; 61 | } 62 | 63 | loliTypeClass(std::string id, const char* tp){ 64 | this->parentType = typeOBJ; 65 | this->identifier = id; 66 | this->ti = tp; 67 | } 68 | 69 | loliTypeClass(loliTypeClass* type, std::string id){ 70 | this->parentType = type; 71 | this->identifier = id; 72 | } 73 | 74 | loliTypeClass(loliTypeClass* type, std::string id, const char* tp){ 75 | this->parentType = type; 76 | this->identifier = id; 77 | this->ti = tp; 78 | } 79 | 80 | bool isFrom(loliTypeClass* o){ 81 | //when typeA <= typeB, typeA is an inheritor of typeB, e.g. typeINT <= typeNUM 82 | std::cout<toString()<<"\t"<toString()<parentType->isFrom(o); 93 | } 94 | } 95 | } 96 | 97 | ~loliTypeClass(){} 98 | }; 99 | 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /src/LoLi2/include/loli_typeenv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_typeenv.h 5 | * 6 | * Description: Type Env of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 08/30/2014 06:57:39 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_TYPEENV_ 20 | #define __LOLI_TYPEENV_ 21 | 22 | #include "loli_obj.h" 23 | #include "loli_util.h" 24 | #include "loli_typeclass.h" 25 | 26 | #define MAX_TYPES 8192 27 | 28 | class typeEntry { 29 | public: 30 | loliSym* id; 31 | loliTypeClass* type; 32 | 33 | typeEntry(){} 34 | 35 | typeEntry(loliTypeClass* tp){ 36 | id = SYM(tp->identifier); 37 | type = tp; 38 | } 39 | 40 | typeEntry(loliObj* i, loliTypeClass* tp){ 41 | id = lsym(i); 42 | type = tp; 43 | } 44 | }; 45 | 46 | class typeEnv { 47 | public: 48 | typeEntry types[MAX_TYPES]; 49 | int count = 0; 50 | 51 | typeEnv(){ 52 | count = 0; 53 | } 54 | 55 | bool isEmpty(){ 56 | return count == 0; 57 | } 58 | 59 | bool isFull(){ 60 | return count == MAX_TYPES; 61 | } 62 | 63 | typeEntry* queryType(loliObj* id){ 64 | for(int i = 0; i < count; i++){ 65 | if((&types[i])->id == lsym(id)){ 66 | return &types[i]; 67 | } 68 | } 69 | return NULL; 70 | } 71 | 72 | void addType(typeEntry* type){ 73 | if(isFull()){ 74 | loli_err("Type Space Overflow!"); 75 | return; 76 | } 77 | if(queryType(type->id)){ 78 | loli_err("Type Already Exists!"); 79 | } 80 | types[++count] = *type; 81 | } 82 | 83 | void removeType(loliObj* id){ 84 | if(!queryType(id)){ 85 | for(int i = 0; i < count; i++){ 86 | if((&types[i])->id == lsym(id)){ 87 | for(int j = i; j < count; j++){ 88 | types[j] = types[j + 1]; 89 | } 90 | return; 91 | } 92 | } 93 | } 94 | loli_err("Type: " + id->toString() + " not found!"); 95 | } 96 | 97 | void overrideType(typeEntry* type){ 98 | if(queryType(type->id)){ 99 | loli_err("Type cannot be overriden!"); 100 | return; 101 | }else{ 102 | for(int i = 0; i < count ; i++){ 103 | if((&types[i])->id == type->id){ 104 | types[i] = *type; 105 | return; 106 | } 107 | } 108 | } 109 | } 110 | }; 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /src/LoLi2/include/loli_util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_util.h 5 | * 6 | * Description: Utilities of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/26/2014 06:52:14 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #ifndef __LOLI_UTIL_ 20 | #define __LOLI_UTIL_ 21 | 22 | #include 23 | #include "loli_obj.h" 24 | 25 | extern void loli_err(std::string err); 26 | extern std::string pairUp(std::string str); 27 | extern bool is_spchar(char c); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/LoLi2/loli2test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli2test.cpp 5 | * 6 | * Description: Test of LoLi 2 7 | * 8 | * Version: 1.0 9 | * Created: 06/26/2014 02:20:22 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "include/loli_obj.h" 25 | #include "include/loli_util.h" 26 | #include "include/loli_stack.h" 27 | #include "include/loli_reader.h" 28 | #include "include/loli_parser.h" 29 | #include "include/loli_eval.h" 30 | #include "include/loli_prim.h" 31 | #include "include/loli_env.h" 32 | #include "include/loli_typeclass.h" 33 | #include "include/loli_lambda.h" 34 | 35 | using namespace std; 36 | 37 | int main(){ 38 | add_to_top_env(to_env_entry(SYM("t"), t)); 39 | add_to_top_env(to_env_entry(SYM("quote"), PROC(c_quote, KEY("OBJ"), KEY("OBJ")))); 40 | add_to_top_env(to_env_entry(SYM("+"), PROC(c_plus, KEY("NUM"), KEY("NUM")))); 41 | add_to_top_env(to_env_entry(SYM("-"), PROC(c_sub, KEY("NUM"), KEY("NUM")))); 42 | add_to_top_env(to_env_entry(SYM("*"), PROC(c_mult, KEY("NUM"), KEY("NUM")))); 43 | add_to_top_env(to_env_entry(SYM("/"), PROC(c_div, KEY("NUM"), KEY("NUM")))); 44 | add_to_top_env(to_env_entry(SYM("\\"), PROC(c_lambda, KEY("LAMBDA"), KEY("CONS")))); 45 | 46 | while(true){ 47 | cout<<"Get Input: "; 48 | string tmp = read_pair(); 49 | // cout<<"Input: "<eval(top_env)->toString()< 26 | 27 | loliObj* c_apply (loliObj* fn, loliObj* args, loliObj* env){ 28 | std::cout<toString()<<"\t"<type->toString()<proc){ 30 | std::cout<<"PROC:\t"<<&(lproc(fn)->proc)<proc(args); 32 | }else if(llambda(fn)->exp){ 33 | std::cout<<"LAMBDA"<env;!lcons(e)->head()->nilp() ; e = lcons(e)->tail()){ 36 | tmpe = add_to_env(to_env_entry(lcons(e)->head(), lcons(args)->head()), tmpe); 37 | args = lcons(args)->tail(); 38 | } 39 | return llambda(fn)->exp->eval(tmpe); 40 | }else{ 41 | loli_err(fn->toString() + " is not appliable!"); 42 | return nil; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/LoLi2/loli_cbmi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_cbmi.cpp 5 | * 6 | * Description: Context Based Meaning Inference System 7 | * 8 | * Version: 1.0 9 | * Created: 07/21/2014 09:59:22 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "include/loli_obj.h" 20 | #include "include/loli_env.h" 21 | #include "include/loli_type.h" 22 | #include "include/loli_util.h" 23 | 24 | loliObj* build_sexp(loliObj* orig){ 25 | if(nilp(orig)){ 26 | return nil; 27 | } 28 | if(is_sym(orig)){ 29 | loliObj* tmp; 30 | if(orig->env != NULL || !nilp(orig->env)){ 31 | tmp = lookup_env(orig, orig->env); 32 | }else{ 33 | tmp = lookup_top_env(orig); 34 | } 35 | if(nilp(tmp)){ 36 | loli_err("Symbol " + toString(orig) + " is unbound!"); 37 | } 38 | return tmp; 39 | } 40 | if(is_int(orig) || is_flt(orig)){ 41 | return orig; 42 | } 43 | if(is_cons(orig)){ 44 | 45 | } 46 | return orig; 47 | } 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/LoLi2/loli_env.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_env.cpp 5 | * 6 | * Description: Env of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 07/17/2014 12:02:03 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "include/loli_obj.h" 20 | #include "include/loli_typeclass.h" 21 | #include "include/loli_util.h" 22 | 23 | #include 24 | 25 | loliCons* top_env = CONS(CONS(SYM("nil"), nil), nil); 26 | 27 | loliCons* to_env_entry(loliObj* sym, loliObj* value){ 28 | return CONS(sym, value); 29 | } 30 | 31 | loliCons* add_to_env(loliObj* obj, loliObj* env){ 32 | return CONS(obj, env); 33 | } 34 | 35 | void add_to_top_env(loliObj* obj){ 36 | top_env = add_to_env(obj, top_env); 37 | } 38 | 39 | loliObj* lookup_env(loliObj* sym, loliObj* env){ 40 | loliObj* result = nil; 41 | for(auto e = env; !e->nilp(); e = lcons(e)->tail()){ 42 | // std::cout<head()->toString()<head())->head())->type->toString()<head())->head())->equal(lsym(sym))){ 45 | result = CONS(lcons(lcons(e)->head())->tail(), result); 46 | } 47 | } 48 | return result; 49 | } 50 | 51 | loliObj* lookup_top_env(loliObj* sym){ 52 | return lookup_env(sym, top_env); 53 | } 54 | 55 | loliObj* get_type(loliTypeClass* type, loliObj* sym, loliObj* env){ 56 | loliObj* tmp = lookup_env(sym, env); 57 | if(tmp->nilp()){ 58 | return nil; 59 | } 60 | for(loliObj* e = tmp; !e->nilp(); e = lcons(e)->tail()){ 61 | if(lcons(e)->head()->type->isFrom(type)){ 62 | return lcons(e)->head(); 63 | } 64 | } 65 | return nil; 66 | } 67 | 68 | loliObj* c_def(loliObj* obj){ 69 | loliObj* sym = lsym(lcons(obj)->head()); 70 | loliObj* value = lcons(lcons(obj)->tail())->head(); 71 | if(!get_type(value->type, sym, top_env)->nilp()){ 72 | loli_err("Object: "+ sym->toString() +" already exist, use set! to change the value"); 73 | return nil; 74 | }else{ 75 | add_to_top_env(to_env_entry(sym, value)); 76 | return value; 77 | } 78 | } 79 | 80 | loliObj* c_set(loliObj* obj){ 81 | loliObj* sym = lsym(lcons(obj)->head()); 82 | loliObj* value = lcons(lcons(obj)->tail())->head(); 83 | if(get_type(value->type, sym, top_env)->nilp()){ 84 | loli_err("Symbol: "+ sym->toString() +" is not defined with this type, ues def to define"); 85 | return nil; 86 | }else{ 87 | *get_type(value->type, sym, top_env) = *to_env_entry(sym, value); 88 | return to_env_entry(sym, value); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/LoLi2/loli_eval.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_eval.cpp 5 | * 6 | * Description: Eval of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 07/18/2014 11:16:31 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "include/loli_obj.h" 20 | #include "include/loli_env.h" 21 | #include "include/loli_util.h" 22 | #include "include/loli_apply.h" 23 | 24 | #include 25 | #include 26 | 27 | loliObj* eval_list(loliObj* lst, loliObj* env); 28 | 29 | loliObj* loliSym::eval(loliObj* e){ 30 | this->type = typeSYM; 31 | if(this->name == "nil" || this == nil){ 32 | return nil; 33 | } 34 | if(this->name == "t" || this == t){ 35 | return t; 36 | } 37 | if(e->nilp() || e == NULL){ 38 | loliObj* r = lookup_top_env(this); 39 | if(r->nilp()){ 40 | loli_err("Symbol: " + this->toString() + " is not bound."); 41 | return nil; 42 | }else{ 43 | return lcons(r)->head(); 44 | } 45 | }else{ 46 | loliObj* r = lookup_env(this, e); 47 | if(r->nilp()){ 48 | loli_err("Symbol: " + this->toString() + " is not bound in its environment."); 49 | return nil; 50 | }else{ 51 | return lcons(r)->head(); 52 | } 53 | } 54 | } 55 | 56 | loliObj* loliCons::eval(loliObj* env){ 57 | this->type = typeCONS; 58 | // std::cout<type->toString()<head() == SYM("if")){ 60 | loliObj* cond = lcons(this->tail())->head(); 61 | if(this->tail()->nilp()){ 62 | loli_err("Need at least one expression for if"); 63 | return nil; 64 | } 65 | loliObj* wt = lcons(lcons(this->tail())->tail())->head(); 66 | loliObj* wf = lcons(lcons(lcons(this->tail())->tail())->tail())->head(); 67 | if(cond->eval(env)==boolt){ 68 | return wt->eval(top_env); 69 | }else if(cond->eval(env)==boolf){ 70 | if(wf){ 71 | return wf->eval(top_env); 72 | }else{ 73 | return nil; 74 | } 75 | }else{ 76 | loli_err("Condition error"); 77 | return nil; 78 | } 79 | } 80 | return eval_list(this, env); 81 | } 82 | 83 | loliObj* eval_list(loliObj* lst, loliObj* env){ 84 | loliObj* car = lcons(lst)->head()->eval(env); 85 | loliObj* cdr = lcons(lst)->tail(); 86 | std::cout<<"HEAD: "<toString()<<"\tTAIL: "<toString()<type->toString()<rtype){ 89 | if(lcons(lcons(lcons(cdr)->tail())->head())->hd == NULL){ 90 | std::cout<tail())->head())->toString()<eval(env), env); 92 | } 93 | return c_apply(car, cdr, env); 94 | } 95 | else{ 96 | loli_err(car->toString() + " is not a function!"); 97 | } 98 | return nil; 99 | } 100 | -------------------------------------------------------------------------------- /src/LoLi2/loli_lambda.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_lambda.cpp 5 | * 6 | * Description: Lambda of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 09/26/2014 03:33:00 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "include/loli_obj.h" 20 | #include "include/loli_typeclass.h" 21 | 22 | #include 23 | 24 | loliObj* c_lambda(loliObj* exp){ 25 | auto s = lcons(exp)->head(); //Return type 26 | auto a = lcons(lcons(exp)->tail())->head(); //Arg List 27 | auto e = lcons(lcons(lcons(exp)->tail())->tail())->head(); //Exp 28 | return LAMBDA(lkey(s), a, e); 29 | } 30 | -------------------------------------------------------------------------------- /src/LoLi2/loli_main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_main.cpp 5 | * 6 | * Description: The entrance of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 07/11/2014 05:19:25 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "include/loli_repl.h" 24 | #include "include/loli_obj.h" 25 | #include "include/loli_env.h" 26 | #include "include/loli_prim.h" 27 | #include "include/loli_type.h" 28 | 29 | #define VERSION "Dev alpha 2" 30 | 31 | void showHelp(); 32 | 33 | loliObj* initTopEnv(); 34 | 35 | int main(int argc, char** argv){ 36 | if(argc >= 2){ 37 | if(strcmp(argv[1], "--eval") == 0){ 38 | //Eval from command line 39 | std::cout<<"EVAL"< 21 | #include 22 | #include 23 | #include "include/loli_obj.h" 24 | 25 | loliObj* nil = new loliSym("nil"); 26 | loliObj* t = new loliSym("t"); 27 | loliObj* quote = new loliSym("quote"); 28 | 29 | loliObj* boolt = new loliBool(true); 30 | loliObj* boolf = new loliBool(false); 31 | -------------------------------------------------------------------------------- /src/LoLi2/loli_parser.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_parser.cpp 5 | * 6 | * Description: Parser of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 07/04/2014 03:07:21 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "include/loli_obj.h" 20 | #include "include/loli_util.h" 21 | 22 | #include 23 | #include 24 | 25 | loliObj* parse_list(std::string str, loliObj* env); 26 | 27 | loliObj* parse_string(std::string str, loliObj* env){ 28 | while(isspace(str[0])){ 29 | str = str.substr(1); 30 | } 31 | if(str[0] == '\0'){ 32 | return nil; 33 | } 34 | if(str[0] == '\''){ 35 | loliCons* tmp = CONS(quote, CONS(parse_string(str.substr(1), env), nil)); 36 | tmp->env = env; 37 | return tmp; 38 | } 39 | if(str[0] == '\"'){ 40 | for(ulong i = 1; i < str.length(); i++){ 41 | if(str[i] == '\"'){ 42 | loliString* tmp = STRING(str.substr(1, i - 1)); 43 | tmp->env = env; 44 | return tmp; 45 | } 46 | } 47 | loliString* tmp = STRING(str.substr(1, str.length() - 2)); 48 | tmp->env = env; 49 | return tmp; 50 | } 51 | if(str[0] == ':'){ 52 | for(ulong i = 1; i < str.length(); i++){ 53 | if(is_spchar(str[i])){ 54 | if(i != 1){ 55 | loliKey* tmp = KEY(str.substr(1, i)); 56 | tmp->env = env; 57 | return tmp; 58 | }else{ 59 | loli_err("Empty Keyword!"); 60 | return nil; 61 | } 62 | } 63 | } 64 | loliKey* tmp = KEY(str.substr(1)); 65 | tmp->env = env; 66 | return tmp; 67 | } 68 | if(str[0] == '('){ 69 | auto* tmp = parse_list(str.substr(1, str.length() - 2), env); 70 | tmp->env = env; 71 | return tmp; 72 | } 73 | try{ 74 | if(stol(str) == stold(str)){ 75 | loliInt* tmp = INT(stol(str)); 76 | tmp->env = env; 77 | return tmp; 78 | }else{ 79 | loliFlt* tmp = FLT(stold(str)); 80 | tmp->env = env; 81 | return tmp; 82 | } 83 | }catch(...){ 84 | 85 | } 86 | for(ulong i = 0; i < str.length(); i++){ 87 | if(isspace(str[i])){ 88 | return SYM(str.substr(0, i)); 89 | } 90 | } 91 | //Default return is a symbol 92 | loliSym* tmp = SYM(str); 93 | tmp->env = env; 94 | return tmp; 95 | } 96 | 97 | loliObj* parse_list(std::string str, loliObj* env){ 98 | while(isspace(str[0])){ 99 | str = str.substr(1); 100 | } 101 | if(str[0] == '\0'){ 102 | return nil; 103 | } 104 | for(ulong i = 0; i < str.length(); i++){ 105 | if(isspace(str[i])){ 106 | loliObj* tmp = CONS(parse_string(str.substr(0, i), env), parse_list(str.substr(i + 1), env)); 107 | tmp->env = env; 108 | return tmp; 109 | } 110 | if(str[i] == '('){ 111 | std::string tmp = pairUp(str.substr(i)); 112 | loliObj* tm = CONS(parse_string(tmp, env), parse_list(str.substr(i + tmp.length()), env)); 113 | tm->env = env; 114 | return tm; 115 | } 116 | } 117 | if(parse_string(str, env)->nilp()){ 118 | return CONS(nil, nil); 119 | } 120 | loliObj* tmp = CONS(parse_string(str, env), nil); 121 | tmp->env = env; 122 | return tmp; 123 | } 124 | -------------------------------------------------------------------------------- /src/LoLi2/loli_prim.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_prim.cpp 5 | * 6 | * Description: Primitive Functions of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 07/18/2014 01:08:45 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "include/loli_obj.h" 20 | #include "include/loli_util.h" 21 | #include "include/loli_typeclass.h" 22 | 23 | loliObj* c_plus(loliObj* obj){ 24 | double tmp = 0; 25 | for(loliObj* o = obj; !o->nilp(); o = lcons(o)->tail()){ 26 | if(lcons(o)->head()->type->isFrom(typeNUM)){ 27 | tmp = tmp + lnum(lcons(o)->head())->getValue(); 28 | } 29 | else{ 30 | loli_err(lcons(o)->head()->toString() + " is not a number!"); 31 | return INT(0); 32 | } 33 | } 34 | if((long) tmp == tmp){ 35 | return INT((long)tmp); 36 | }else{ 37 | return FLT(tmp); 38 | } 39 | } 40 | 41 | loliObj* c_mult(loliObj* obj){ 42 | double tmp = 0; 43 | for(loliObj* o = obj; !o->nilp(); o = lcons(o)->tail()){ 44 | if(lcons(o)->head()->type->isFrom(typeNUM)){ 45 | tmp = tmp * lnum(lcons(o)->head())->getValue(); 46 | } 47 | else{ 48 | loli_err(lcons(o)->head()->toString() + " is not a number!"); 49 | return INT(0); 50 | } 51 | } 52 | if((long) tmp == tmp){ 53 | return INT((long)tmp); 54 | }else{ 55 | return FLT(tmp); 56 | } 57 | } 58 | 59 | loliObj* c_sub(loliObj* obj){ 60 | double tmp = lnum(lcons(obj)->head())->getValue(); 61 | obj = lcons(obj)->tail(); 62 | for(loliObj* o = obj; !o->nilp(); o = lcons(o)->tail()){ 63 | if(lcons(o)->head()->type->isFrom(typeNUM)){ 64 | tmp = tmp - lnum(lcons(o)->head())->getValue(); 65 | } 66 | else{ 67 | loli_err(lcons(o)->head()->toString() + " is not a number!"); 68 | return INT(0); 69 | } 70 | } 71 | if((long) tmp == tmp){ 72 | return INT((long)tmp); 73 | }else{ 74 | return FLT(tmp); 75 | } 76 | } 77 | 78 | loliObj* c_div(loliObj* obj){ 79 | double tmp = lnum(lcons(obj)->head())->getValue(); 80 | obj = lcons(obj)->tail(); 81 | for(loliObj* o = obj; !o->nilp(); o = lcons(o)->tail()){ 82 | if(lcons(o)->head()->type->isFrom(typeNUM)){ 83 | if(lnum(lcons(o)->head())->getValue() != 0){ 84 | tmp = tmp / lnum(lcons(o)->head())->getValue(); 85 | }else{ 86 | loli_err("Error! Divide by ZERO!"); 87 | return INT(0); 88 | } 89 | } 90 | else{ 91 | loli_err(lcons(o)->head()->toString() + " is not a number!"); 92 | return INT(0); 93 | } 94 | } 95 | if((long) tmp == tmp){ 96 | return INT((long)tmp); 97 | }else{ 98 | return FLT(tmp); 99 | } 100 | } 101 | 102 | loliObj* c_quote(loliObj* obj){ 103 | return lcons(obj)->head(); 104 | } 105 | -------------------------------------------------------------------------------- /src/LoLi2/loli_reader.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_reader.cpp 5 | * 6 | * Description: Reader of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/26/2014 06:36:29 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "include/loli_obj.h" 25 | #include "include/loli_util.h" 26 | 27 | std::string loli_getline(){ //HANDLE CTRL+D 28 | std::string tmp; 29 | while(true){ 30 | getline(std::cin, tmp); 31 | if(std::cin.eof()){ 32 | std::exit(1); 33 | } 34 | return tmp; 35 | } 36 | } 37 | 38 | std::string read_pair(int i, bool quote){ 39 | std::string tmp; 40 | tmp = loli_getline(); 41 | int p = i; 42 | bool q = quote; 43 | for(ulong j = 0; j < tmp.length(); j++){ 44 | if(tmp[j] == ';'){ 45 | //Comment 46 | tmp = tmp.substr(0, j); 47 | break; 48 | } 49 | if(tmp[j] == '"'){ 50 | //Quote 51 | q = !q; 52 | } 53 | if(tmp[j] == '('){ 54 | if(!q){ 55 | p = p + 1; 56 | } 57 | }else if(tmp[j] == ')'){ 58 | if(!q){ 59 | p = p - 1; 60 | } 61 | } 62 | if(p < 0){ 63 | loli_err("Warning! Unpaired ) found!"); 64 | tmp = tmp.substr(0, j); 65 | p = p + 1; 66 | break; 67 | } 68 | } 69 | if(p == 0 && !q){ 70 | return tmp; 71 | }else{ 72 | return tmp.append(read_pair(p, q)); 73 | } 74 | } 75 | 76 | std::string read_pair(){ 77 | return read_pair(0, false); 78 | } 79 | 80 | std::string read_pair(int i, bool quote, std::ifstream &stream){ 81 | std::string tmp; 82 | std::getline(stream, tmp); 83 | int p = i; 84 | bool q = quote; 85 | for(ulong j = 0; j < tmp.length(); j++){ 86 | if(tmp[j] == ';'){ 87 | //Comment 88 | tmp = tmp.substr(0, j); 89 | break; 90 | } 91 | if(tmp[j] == '"'){ 92 | //Quote 93 | q = !q; 94 | } 95 | if(tmp[j] == '('){ 96 | if(!q){ 97 | p = p + 1; 98 | } 99 | }else if(tmp[j] == ')'){ 100 | if(!q){ 101 | p = p - 1; 102 | } 103 | } 104 | if(p < 0){ 105 | loli_err("Warning! Unpaired ) found!"); 106 | tmp = tmp.substr(0, j); 107 | p = p + 1; 108 | break; 109 | } 110 | } 111 | if(p == 0 && !q){ 112 | return tmp; 113 | }else{ 114 | return tmp.append(read_pair(p, q, stream)); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/LoLi2/loli_repl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_repl.cpp 5 | * 6 | * Description: REPL of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 08/08/2014 10:28:56 AM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "include/loli_obj.h" 20 | #include "include/loli_env.h" 21 | #include "include/loli_eval.h" 22 | #include "include/loli_reader.h" 23 | #include "include/loli_util.h" 24 | #include "include/loli_parser.h" 25 | 26 | #include 27 | 28 | void c_repl(loliObj* env){ 29 | while(true){ 30 | std::cout<<"LoLi > "; 31 | std::string input = read_pair(); 32 | try{ 33 | //EVAL 34 | loliObj* exp = parse_string(input, env); 35 | std::cout<eval(env)->toString()< 20 | 21 | #include "include/loli_obj.h" 22 | #include "include/loli_stack.h" 23 | #include "include/loli_util.h" 24 | 25 | loliStack global_stack; 26 | 27 | std::string stack_to_string(loliStack stack){ 28 | std::string tmp = ""; 29 | for(int i = 0 ; i < stack.obj_in_stack; i++){ 30 | tmp = tmp + "Stack [" + std::to_string(i) + "]: " + (&stack.stack[i])->toString() + "\n"; 31 | } 32 | return tmp; 33 | } 34 | -------------------------------------------------------------------------------- /src/LoLi2/loli_type.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_type.cpp 5 | * 6 | * Description: Type of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 07/17/2014 01:37:02 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "include/loli_obj.h" 20 | #include "include/loli_type.h" 21 | 22 | loliObj* c_is_int(loliObj* obj){ 23 | return is_int(obj) ? boolt : boolf; 24 | } 25 | 26 | loliObj* c_is_flt(loliObj* obj){ 27 | return is_flt(obj) ? boolt : boolf; 28 | } 29 | 30 | loliObj* c_is_num(loliObj* obj){ 31 | return is_flt(obj) || is_int(obj) ? boolt : boolf; 32 | } 33 | 34 | loliObj* c_is_sym(loliObj* obj){ 35 | return is_sym(obj) ? boolt : boolf; 36 | } 37 | 38 | loliObj* c_is_proc(loliObj* obj){ 39 | return is_proc(obj) ? boolt : boolf; 40 | } 41 | 42 | loliObj* c_is_cons(loliObj* obj){ 43 | return is_cons(obj) ? boolt : boolf; 44 | } 45 | 46 | loliObj* c_is_lambda(loliObj* obj){ 47 | return is_lambda(obj) ? boolt : boolf; 48 | } 49 | 50 | loliObj* c_is_char(loliObj* obj){ 51 | return is_char(obj) ? boolt : boolf; 52 | } 53 | 54 | loliObj* c_is_str(loliObj* obj){ 55 | return is_str(obj) ? boolt : boolf; 56 | } 57 | 58 | loliObj* c_is_bool(loliObj* obj){ 59 | return is_bool(obj) ? boolt : boolf; 60 | } 61 | 62 | loliObj* c_is_key(loliObj* obj){ 63 | return is_key(obj) ? boolt : boolf; 64 | } 65 | 66 | loliObj* c_is_type(loliObj* obj){ 67 | return is_type(obj) ? boolt : boolf; 68 | } 69 | 70 | loliObj* c_is_obj(loliObj* obj){ 71 | return boolt; 72 | } 73 | 74 | -------------------------------------------------------------------------------- /src/LoLi2/loli_typeclass.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_typeclass.cpp 5 | * 6 | * Description: Typeclass of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 08/30/2014 03:26:26 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "include/loli_env.h" 20 | #include "include/loli_typeclass.h" 21 | #include 22 | 23 | using namespace std; 24 | 25 | loliTypeClass* typeOBJ = new loliTypeClass("OBJ", typeid(loliObj*).name()); 26 | loliTypeClass* typeNUM = new loliTypeClass(typeOBJ, "NUM", typeid(loliNum*).name()); 27 | loliTypeClass* typeINT = new loliTypeClass(typeNUM, "INT", typeid(loliInt*).name()); 28 | loliTypeClass* typeFLT = new loliTypeClass(typeNUM, "FLT", typeid(loliFlt*).name()); 29 | loliTypeClass* typeSYM = new loliTypeClass(typeOBJ, "SYM", typeid(loliSym*).name()); 30 | loliTypeClass* typeKEY = new loliTypeClass(typeOBJ, "KEY", typeid(loliKey*).name()); 31 | loliTypeClass* typeCONS = new loliTypeClass(typeOBJ, "CONS", typeid(loliCons*).name()); 32 | loliTypeClass* typeFN = new loliTypeClass(typeOBJ, "FUNC", typeid(loliFunction*).name()); 33 | loliTypeClass* typeLAMBDA = new loliTypeClass(typeFN, "LAMBDA", typeid(loliLambda*).name()); 34 | loliTypeClass* typePROC = new loliTypeClass(typeFN, "PROC", typeid(loliPrim*).name()); 35 | loliTypeClass* typeCHAR = new loliTypeClass(typeOBJ, "CHAR", typeid(loliChar*).name()); 36 | loliTypeClass* typeSTRING = new loliTypeClass(typeOBJ, "STRING", typeid(loliString*).name()); 37 | loliTypeClass* typeBOOL = new loliTypeClass(typeKEY, "BOOL", typeid(loliBool*).name()); 38 | -------------------------------------------------------------------------------- /src/LoLi2/loli_typeenv.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_typeenv.cpp 5 | * 6 | * Description: Type Env of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 08/30/2014 06:56:29 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include "include/loli_obj.h" 20 | #include "include/loli_typeclass.h" 21 | #include "include/loli_typeenv.h" 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/LoLi2/loli_util.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: loli_util.cpp 5 | * 6 | * Description: Utilities of LoLi 7 | * 8 | * Version: 1.0 9 | * Created: 06/26/2014 06:46:23 PM 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: Z.Shang (), shangzhanlin@gmail.com 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | #include 20 | #include 21 | #include "include/loli_obj.h" 22 | 23 | void loli_err(std::string err){ 24 | std::cerr< ? @ ^ \_ ~ 27 | 28 | For the time being, inline hex escape and vertical bars are not supported. 29 | 30 | Here are some valid identifiers: 31 | 32 | * lambda 33 | * q 34 | * list->vector 35 | * +soup+ 36 | * + 37 | * V17a 38 | * <=? 39 | * a34kTMNs 40 | * ->string 41 | * ... 42 | * this-is-a-very-long-id 43 | 44 | 45 | Also for ease of things, identifiers are case-sensitive. 46 | 47 | 48 | ### boolean (In LoLi, Boolean is Keyword) 49 | 50 | :true and :false, in short, :t and :f 51 | 52 | ### number 53 | 54 | For now integers, float and double would be supported. 55 | For integers, bin, oct, dec and hex would be supported 56 | 57 | * bin: #b10100 58 | * oct: #o24 59 | * dec: #d20 20 60 | * hex: #d14 61 | * float: 3.1415 4.5e4 62 | * double: 2.3d3 2.3D3 63 | 64 | ### string 65 | 66 | Anything between the quote mark is a string, with no quotemark inside 67 | that's not behind a single '\'. 68 | 69 | "\"To be or not to be?\" He whispered to himself." 70 | 71 | '\' serves as a escape sign, the following characters could be escaped: 72 | 73 | * \a bell char 74 | * \b backspace char 75 | * \t tab 76 | * \n return 77 | * \r return 78 | * \" quotemark 79 | * \\\\ backslash 80 | * \\\ escaped line ending. Continue with next line. 81 | 82 | 83 | ### special characters 84 | 85 | Special characters are those special signs not included in identifiers, 86 | they would not be included in any identifiers. For example, the 87 | following are examples of special characters: 88 | 89 | ( ) , \` 90 | 91 | 92 | ### Tokenizer specifications 93 | 94 | ``` 95 | token -> 96 | | 97 | | 98 | | 99 | | 100 | | ( 101 | | ) 102 | | #( 103 | | #u8 104 | | ' 105 | | ` 106 | | , 107 | | ,@ 108 | | . 109 | ``` 110 | 111 | 112 | ## Parser and Language Syntax 113 | 114 | 115 | 116 | 117 | ``` 118 | −> 119 | | 120 | | 121 | | 122 | | 123 | | 124 | | 125 | | 126 | | 127 | ``` 128 | -------------------------------------------------------------------------------- /src/Parser/Tokenizer.cpp: -------------------------------------------------------------------------------- 1 | // --*- C++ -*-------------------------------------// 2 | // 3 | // The Loli Language 4 | // 5 | // 6 | // filename: Tokenizer.h 7 | // descript: The tokens definition and tokenizer 8 | // implementation 9 | // author : Kevin Hu 10 | // note: 11 | // 12 | //-------------------------------------------------// 13 | 14 | 15 | #include "Tokenizer.h" 16 | 17 | 18 | using namespace marklang; 19 | using namespace tokenizer; 20 | 21 | 22 | // --------------------------- // 23 | // Token class 24 | // --------------------------- // 25 | 26 | // Constructor 27 | // param: type - the type of Token 28 | // param: token - the string of token 29 | // param: linum - the line number of token 30 | Token::Token(TokenType type, std::string &token, int linum) 31 | :type(type), token(token), linum(linum){} 32 | 33 | // Destructor 34 | Token::~Token() { } 35 | 36 | 37 | // --------------------------- // 38 | // Token class 39 | // --------------------------- // 40 | // Constructor 41 | Tokenizer::Tokenizer() { } 42 | 43 | 44 | // Destructor 45 | Tokenizer::~Tokenizer() { } 46 | 47 | 48 | // Find the type of the incoming character 49 | // param: c - the input char 50 | // return: the chartype of the input char 51 | CharType Tokenizer::findCharType(char c) 52 | { 53 | if ('0' <= c && c <= '9') { 54 | return NUMBER_CHAR; 55 | } 56 | 57 | if (('a' <= c && c <= 'z') || 58 | ('A' <= c && c <= 'Z')) { 59 | return ALPHA_CHAR; 60 | } 61 | 62 | if (c == '!' || c == '$' 63 | || c == '%' || c == '&' 64 | || c == '*' || c == '+' 65 | || c == '-' || c == '.' 66 | || c == '/' || c == ':' 67 | || c == '=' || c == '>' 68 | || c == '?' || c == '@' 69 | || c == '^' || c == '_' 70 | || c == '~') { 71 | return SPECIAL_IDEN; 72 | } 73 | 74 | if (c == ' ' || c == '\n' || 75 | c == '\r' || c == '\t') { 76 | return EMPTY_CHAR; 77 | } 78 | 79 | if (c == ';') { 80 | return COMMENT_CHAR; 81 | } 82 | 83 | if (c == EOF) { 84 | return END_CHAR; 85 | } 86 | 87 | return SPECIAL_CHAR; 88 | } 89 | 90 | 91 | // Scan the next char from file, save token stream to 92 | // token_stream vector 93 | // param: file - the input file 94 | void Tokenizer::scan(std::istream &file) 95 | { 96 | std::string buffer; 97 | 98 | int linum = 1; 99 | char c; 100 | char next; 101 | 102 | while (file.get(c)) { 103 | buffer.clear(); 104 | 105 | // IDENTIFIER 106 | if (findCharType(c) == ALPHA_CHAR 107 | || findCharType(c) == SPECIAL_IDEN) { 108 | buffer += c; 109 | while(file.get(next)) { 110 | if (findCharType(next) == ALPHA_CHAR 111 | || findCharType(next) == SPECIAL_IDEN 112 | || findCharType(next) == NUMBER_CHAR) { 113 | buffer += next; 114 | } 115 | else { 116 | break; 117 | } 118 | } 119 | file.putback(next); 120 | 121 | if (buffer == ":t" || buffer == ":f" 122 | || buffer == ":true" || buffer == ":false") { 123 | token_stream.push_back(Token(BOOLEAN, buffer, linum)); 124 | } 125 | else { 126 | token_stream.push_back(Token(NAME, buffer, linum)); 127 | } 128 | continue; 129 | } 130 | 131 | // NUMBERS 132 | if (findCharType(c) == NUMBER_CHAR) { 133 | int state = 0; 134 | buffer += c; 135 | 136 | // starting FSM 137 | while (file.get(next)) { 138 | switch (state) { 139 | case 0: 140 | if (findCharType(next) == NUMBER_CHAR) { 141 | buffer += next; 142 | } 143 | else if (next == '.') { 144 | buffer += next; 145 | state = 1; 146 | } 147 | else if (next == 'e' || next == 'E' 148 | || next == 'd' || next == 'D') { 149 | buffer += next; 150 | state = 2; 151 | } 152 | else if (findCharType(next) == SPECIAL_CHAR 153 | || findCharType(next) == SPECIAL_IDEN 154 | || findCharType(next) == EMPTY_CHAR) { 155 | state = 5; 156 | } 157 | else { 158 | state = -1; 159 | } 160 | break; 161 | case 1: 162 | if (findCharType(next) == NUMBER_CHAR) { 163 | buffer += next; 164 | } 165 | else if (next == 'e' || next == 'E' 166 | || next == 'd' || next == 'D') { 167 | buffer += next; 168 | state = 2; 169 | } 170 | else if (findCharType(next) == SPECIAL_CHAR 171 | || findCharType(next) == SPECIAL_IDEN 172 | || findCharType(next) == EMPTY_CHAR) { 173 | state = 5; 174 | } 175 | else { 176 | state = -1; 177 | } 178 | break; 179 | case 2: 180 | if (next == '+' || next == '-') { 181 | buffer += next; 182 | state = 3; 183 | } 184 | else if (findCharType(next) == NUMBER_CHAR) { 185 | buffer += next; 186 | state = 4; 187 | } 188 | else { 189 | state = -1; 190 | } 191 | break; 192 | case 3: 193 | if (findCharType(next) == NUMBER_CHAR) { 194 | buffer += next; 195 | state = 4; 196 | } 197 | else { 198 | state = -1; 199 | } 200 | break; 201 | case 4: 202 | if (findCharType(next) == NUMBER_CHAR) { 203 | buffer += next; 204 | } 205 | else if (findCharType(next) == SPECIAL_CHAR 206 | || findCharType(next) == SPECIAL_IDEN 207 | || findCharType(next) == EMPTY_CHAR) { 208 | state = 5; 209 | } 210 | else { 211 | state = -1; 212 | } 213 | break; 214 | case 5: 215 | break; 216 | default: 217 | break; 218 | } 219 | if (state == 5) { 220 | file.putback(next); 221 | token_stream.push_back(Token(NUMBER, buffer, linum)); 222 | break; 223 | } 224 | else if (state == -1) { 225 | file.putback(next); 226 | token_stream.push_back(Token(ERRORTOKEN, buffer, linum)); 227 | break; 228 | } 229 | else { 230 | continue; 231 | } 232 | } 233 | continue; 234 | } 235 | 236 | // COMMENTS 237 | if (findCharType(c) == COMMENT_CHAR) { 238 | while (file.get(next)) { 239 | if (next == '\n' || next == '\r') { 240 | break; 241 | } 242 | } 243 | file.putback(next); 244 | continue; 245 | } 246 | 247 | // SRTING 248 | if (c == '"') { 249 | while (file.get(next)) { 250 | if (next == '"') { 251 | break; 252 | } 253 | if (next == '\\') { 254 | file.get(next); 255 | // Deal with special ASCII chars 256 | switch (next) { 257 | case 'a': buffer += '\a'; 258 | break; 259 | case 'b': buffer += '\b'; 260 | break; 261 | case 'n': buffer += '\n'; 262 | break; 263 | case 'r': buffer += '\r'; 264 | break; 265 | case 't': buffer += '\t'; 266 | break; 267 | case '\\': buffer += '\\'; 268 | break; 269 | case '"': buffer += '"'; 270 | break; 271 | default: 272 | break; 273 | } 274 | } 275 | else { 276 | buffer += next; 277 | } 278 | } 279 | // file.putback(next); 280 | token_stream.push_back(Token(STRING, buffer, linum)); 281 | continue; 282 | } 283 | 284 | // EMPTY 285 | if (findCharType(c) == EMPTY_CHAR) { 286 | if (c == '\n' || c == '\r') { 287 | linum++; 288 | } 289 | while (file.get(next)) { 290 | if (next == '\n' || c == '\r') { 291 | linum++; 292 | } 293 | if (findCharType(next) != EMPTY_CHAR) { 294 | break; 295 | } 296 | } 297 | file.putback(next); 298 | continue; 299 | } 300 | 301 | // SPECIAL 302 | if (findCharType(c) == SPECIAL_CHAR) { 303 | buffer += c; 304 | 305 | switch(c) { 306 | case '`': token_stream.push_back(Token(ACUTE, buffer, linum)); 307 | break; 308 | case ',': token_stream.push_back(Token(COMMA, buffer, linum)); 309 | break; 310 | case '.': token_stream.push_back(Token(DOT, buffer, linum)); 311 | break; 312 | case '(': token_stream.push_back(Token(LEFTPAREN, buffer, linum)); 313 | break; 314 | case ')': token_stream.push_back(Token(RIGHTPAREN, buffer, linum)); 315 | break; 316 | default: 317 | break; 318 | } 319 | continue; 320 | } 321 | 322 | } // while loop 323 | } 324 | 325 | 326 | // Dump token stream for debug 327 | void Tokenizer::dump_tokens() 328 | { 329 | for (std::vector::iterator i = token_stream.begin(); 330 | i != token_stream.end(); 331 | ++i) { 332 | 333 | std::cout << i->type 334 | << "\t" 335 | << i->token 336 | << "\t" 337 | << i->linum 338 | << std::endl; 339 | } 340 | } 341 | 342 | -------------------------------------------------------------------------------- /src/Parser/Tokenizer.h: -------------------------------------------------------------------------------- 1 | // --*- C++ -*-------------------------------------// 2 | // 3 | // The Loli Language 4 | // 5 | // 6 | // filename: Tokenizer.h 7 | // descript: The tokens definition and tokenizer 8 | // implementation 9 | // author : Kevin Hu 10 | // note: 11 | // 12 | //-------------------------------------------------// 13 | 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | 21 | namespace marklang { 22 | namespace tokenizer { 23 | 24 | 25 | // --------------------------- // 26 | // Typedefs and constants 27 | // --------------------------- // 28 | enum CharType 29 | { 30 | ALPHA_CHAR, 31 | NUMBER_CHAR, 32 | EMPTY_CHAR, 33 | COMMENT_CHAR, 34 | SPECIAL_IDEN, 35 | SPECIAL_CHAR, 36 | END_CHAR 37 | }; 38 | 39 | enum TokenType 40 | { 41 | NAME, 42 | NUMBER, 43 | STRING, 44 | BOOLEAN, 45 | LEFTPAREN, 46 | RIGHTPAREN, 47 | SINGLEQUOTE, 48 | ACUTE, 49 | COMMA, 50 | DOT, 51 | // SHARP_LEFTPAREN 52 | // COMMA_AT 53 | EMPTY, 54 | ERRORTOKEN 55 | }; 56 | 57 | 58 | // --------------------------- // 59 | // Token class 60 | // --------------------------- // 61 | class Token 62 | { 63 | public: 64 | // Constructor and Destructor 65 | Token(TokenType type, std::string &token, int linum); 66 | ~Token(); 67 | 68 | TokenType type; 69 | std::string token; 70 | int linum; 71 | }; 72 | 73 | 74 | // --------------------------- // 75 | // Tokenizer class 76 | // --------------------------- // 77 | class Tokenizer 78 | { 79 | public: 80 | // The vector containing all tokens 81 | typedef std::vector TokenStream_t; 82 | TokenStream_t token_stream; 83 | 84 | // Constructor and Destructor 85 | Tokenizer(); 86 | ~Tokenizer(); 87 | 88 | // Scan the next character 89 | void scan(std::istream &file); 90 | 91 | // Dump the token stream 92 | void dump_tokens(); 93 | 94 | private: 95 | // find type of character 96 | CharType findCharType(char c); 97 | }; 98 | 99 | 100 | } // namespace tokenizer 101 | } // namespace marklang 102 | -------------------------------------------------------------------------------- /src/Parser/tests/test_tokenizer.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include 5 | 6 | #include "../Tokenizer.h" 7 | 8 | using namespace marklang; 9 | using namespace tokenizer; 10 | 11 | int main() 12 | { 13 | Tokenizer tokenizer; 14 | 15 | tokenizer.scan(std::cin); 16 | 17 | tokenizer.dump_tokens(); 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/README.mkd: -------------------------------------------------------------------------------- 1 | Source Directories: 2 | =================== 3 | 4 | - CL-Backend - The Common Lisp backend of LoLi 2 5 | - LoLi - The first version of LoLi, stopped 6 | - LoLi2 - LoLi 2 interpreter in C++, paused 7 | - Parser - A parser and tokenizer by *Kevin Hu(hxy9243)* 8 | - vm - The virtual machine of LoLi, just a placeholder for the future development 9 | --------------------------------------------------------------------------------