├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── generated └── local │ ├── FlexLexerLocal.h │ ├── lexer.cpp │ ├── parser.cpp │ ├── parser.hpp │ └── stack.hh ├── moon-logo.png ├── source ├── cli │ └── main.cpp └── lib │ ├── build_config.hpp │ ├── builtins.cpp │ ├── common.cpp │ ├── common.hpp │ ├── compiler.cpp │ ├── compiler.hpp │ ├── lexer.lxx │ ├── opcodes.hpp │ ├── operators.cpp │ ├── output.cpp │ ├── output.hpp │ ├── parser.yxx │ ├── pool.hpp │ ├── registry.hpp │ ├── runtime.cpp │ ├── runtime.hpp │ ├── semantic_check.cpp │ ├── semantic_check.hpp │ ├── symbol_table.cpp │ ├── symbol_table.hpp │ ├── syntax_tree.cpp │ ├── syntax_tree.hpp │ ├── vm.cpp │ └── vm.hpp └── tests ├── cpp ├── run_samples.cpp ├── script_call.cpp └── script_globals.cpp └── script ├── callstack.ml ├── cpp_call.ml ├── enums.ml ├── fibonacci.ml ├── functions.ml ├── gc.ml ├── globals.ml ├── if-else.ml ├── imports.ml ├── loops.ml ├── match.ml ├── native_types.ml ├── structs.ml ├── test-import-1.ml ├── test-import-2.ml └── unused-expr.ml /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | 3 | os: 4 | - linux 5 | - osx 6 | 7 | compiler: 8 | - gcc 9 | - clang 10 | 11 | before_install: 12 | # For the GCC update below... 13 | - if [ $TRAVIS_OS_NAME == linux ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test && sudo apt-get update -qq; fi 14 | 15 | install: 16 | # Update the GCC version if on Linux (needed for C++11 support) 17 | - if [ $TRAVIS_OS_NAME == linux ]; then sudo apt-get install -qq g++-5 && export CXX="g++-5" && export CC="gcc-5"; fi 18 | 19 | # Update/install Bison and Flex on Linux: 20 | - if [ $TRAVIS_OS_NAME == linux ]; then 21 | sudo apt-get update -qq; 22 | sudo apt-get install -qq flex; 23 | wget --no-check-certificate http://ftp.gnu.org/gnu/bison/bison-3.0.4.tar.gz; 24 | mkdir $HOME/bison; 25 | tar -xf bison-3.0.4.tar.gz; 26 | cd bison-3.0.4; 27 | ./configure --prefix=$HOME/bison; 28 | make -j 4 install; 29 | cd $PWD/..; 30 | export PATH=$HOME/bison/bin:$PATH; 31 | fi 32 | 33 | # Bison/Flex update on OSX using Brew: 34 | # (need the unlink hack for OSX, see: http://stackoverflow.com/a/29053701/1198654) 35 | - if [ $TRAVIS_OS_NAME == osx ]; then 36 | brew update; 37 | brew install flex; 38 | brew install bison; 39 | brew unlink flex; 40 | brew unlink bison; 41 | brew link flex --force; 42 | brew link bison --force; 43 | fi 44 | 45 | script: 46 | - $CXX --version 47 | - flex -V 48 | - bison -V 49 | - make 50 | 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Guilherme Lampert 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | #------------------------------------------------ 3 | 4 | # === Available build rules/targets === 5 | # 6 | # - all (default): 7 | # $ make 8 | # Same as debug. 9 | # 10 | # - debug: 11 | # $ make debug 12 | # Enables debug symbols (-g) asserts and 13 | # a few other more costly runtime checks. 14 | # 15 | # - release: 16 | # $ make release 17 | # Build with optimizations turned on (-O3), no assertions, 18 | # no debug symbols and no additional runtime checks. 19 | # 20 | # - static_check: 21 | # $ make static_check 22 | # Runs Clang static analyzer on the source code. 23 | # This will not generate an executable or lib, 24 | # so the linking stage will fail. 25 | # 26 | # - asan: 27 | # $ make asan 28 | # Build in debug mode and with Clang's address sanitizer. 29 | # See: http://clang.llvm.org/docs/AddressSanitizer.html 30 | # 31 | # - test: 32 | # $ make test 33 | # Build the static lib, CLI and test applications in debug mode. 34 | # 35 | # 36 | # === Output === 37 | # 38 | # - moon executable: the Command Line Interpreter (CLI). 39 | # - libMoon.a: static library with the compiler and VM. 40 | # - test_XYZ: each of the test executables. 41 | # 42 | # 43 | # === Other global flags === 44 | # 45 | # - Setting the 'VERBOSE' variable causes the whole 46 | # commands to be printed. If this is not set, 47 | # a short summary is printed for each command 48 | # instead. 49 | # 50 | 51 | #------------------------------------------------ 52 | # Macros / env: 53 | 54 | CLI_BIN = moon 55 | STATIC_LIB = libMoon.a 56 | 57 | GENERATED_DIR = generated 58 | OBJ_DIR = obj 59 | SOURCE_DIR = source/lib 60 | 61 | CLI_SRC = $(wildcard source/cli/*.cpp) 62 | TEST_SRC = $(wildcard tests/cpp/*.cpp) 63 | 64 | MKDIR_CMD = mkdir -p 65 | AR_CMD = ar rcs 66 | STRIP_CMD = strip 67 | 68 | LEX_SRC = $(wildcard $(SOURCE_DIR)/*.lxx) 69 | BISON_SRC = $(wildcard $(SOURCE_DIR)/*.yxx) 70 | CPP_SRC = $(wildcard $(SOURCE_DIR)/*.cpp) 71 | 72 | LEX_GENERATED = $(addprefix $(GENERATED_DIR)/, $(notdir $(patsubst %.lxx, %.cpp, $(LEX_SRC)))) 73 | BISON_GENERATED = $(addprefix $(GENERATED_DIR)/, $(notdir $(patsubst %.yxx, %.cpp, $(BISON_SRC)))) 74 | SRC_FILES = $(BISON_GENERATED) $(LEX_GENERATED) $(CPP_SRC) 75 | OBJ_FILES = $(addprefix $(OBJ_DIR)/, $(patsubst %.cpp, %.o, $(SRC_FILES))) 76 | TEST_OBJ_FILES = $(addprefix $(OBJ_DIR)/, $(patsubst %.cpp, %.o, $(TEST_SRC))) 77 | 78 | # Define 'VERBOSE' to get the full console output. 79 | # Otherwise print a short message for each rule. 80 | ifndef VERBOSE 81 | QUIET = @ 82 | endif # VERBOSE 83 | 84 | # Additional release settings: 85 | RELEASE_FLAGS = -O3 \ 86 | -DNDEBUG=1 \ 87 | -DMOON_DEBUG=0 \ 88 | -DMOON_ENABLE_ASSERT=0 89 | 90 | # Additional debug settings: 91 | DEBUG_FLAGS = -g \ 92 | -DDEBUG=1 \ 93 | -D_DEBUG=1 \ 94 | -D_LIBCPP_DEBUG=0 \ 95 | -D_LIBCPP_DEBUG2=0 \ 96 | -DMOON_DEBUG=1 \ 97 | -DMOON_ENABLE_ASSERT=1 98 | 99 | # Paranoid warning flags: 100 | WARNS_USED = -Wall \ 101 | -Wextra \ 102 | -Wsequence-point \ 103 | -Wdisabled-optimization \ 104 | -Wuninitialized \ 105 | -Wshadow \ 106 | -Wformat=2 \ 107 | -Winit-self \ 108 | -Wwrite-strings 109 | 110 | # Some warnings generated by the Flex and Bison generated code that we can't fix: 111 | WARNS_IGNORED = -Wno-deprecated-register \ 112 | -Wno-unused-function \ 113 | -Wno-sign-compare 114 | 115 | # Additional include commands: 116 | INCLUDE_DIRS = -I. \ 117 | -I/usr/local/include \ 118 | -I$(GENERATED_DIR)/ \ 119 | -I$(SOURCE_DIR)/ 120 | 121 | # Static analysis with Clang: 122 | STATIC_CHECK_FLAGS = --analyze -Xanalyzer -analyzer-output=text 123 | 124 | # Clang address sanitizer (use it with the debug target): 125 | ASAN_FLAGS = -O1 -fno-omit-frame-pointer -fsanitize=address 126 | 127 | # All flags combined: 128 | CXXFLAGS += -std=c++11 \ 129 | $(WARNS_USED) \ 130 | $(WARNS_IGNORED) \ 131 | $(INCLUDE_DIRS) 132 | 133 | #------------------------------------------------ 134 | # CPlusPlus rules: 135 | 136 | # Default rule. Same as debug. 137 | all: CXXFLAGS += $(DEBUG_FLAGS) 138 | all: common_rule 139 | @echo "Note: Built with debug settings (default)." 140 | 141 | # DEBUG: 142 | debug: CXXFLAGS += $(DEBUG_FLAGS) 143 | debug: common_rule 144 | @echo "Note: Built with debug settings." 145 | 146 | # RELEASE: 147 | release: CXXFLAGS += $(RELEASE_FLAGS) 148 | release: common_rule 149 | @echo "Note: Built with release settings." 150 | 151 | # Clang static check: 152 | static_check: CXXFLAGS += $(DEBUG_FLAGS) $(STATIC_CHECK_FLAGS) 153 | static_check: common_rule 154 | @echo "Note: Compiled for static analysis only. No code generated." 155 | 156 | # Clang address sanitizer (ASan): 157 | asan: CXXFLAGS += $(DEBUG_FLAGS) $(ASAN_FLAGS) 158 | asan: common_rule 159 | @echo "Note: Built with address sanitizer enabled and debug settings." 160 | 161 | # Static lib + CLI + tests, in debug mode. 162 | test: CXXFLAGS += $(DEBUG_FLAGS) $(ASAN_FLAGS) 163 | test: common_rule $(TEST_OBJ_FILES) 164 | 165 | $(TEST_OBJ_FILES): $(OBJ_DIR)/%.o: %.cpp 166 | @echo "-> Building test" $< "..." 167 | $(QUIET) $(MKDIR_CMD) $(dir $@) 168 | $(QUIET) $(CXX) $(CXXFLAGS) -c $< -o $@ 169 | $(QUIET) $(CXX) $(CXXFLAGS) $@ -o $(addprefix test_, $(basename $(@F))) $(STATIC_LIB) 170 | 171 | # 172 | # Base rules shared by all the above: 173 | # 174 | 175 | common_rule: $(CLI_BIN) 176 | $(QUIET) $(STRIP_CMD) $(CLI_BIN) 177 | 178 | $(STATIC_LIB): $(OBJ_FILES) 179 | @echo "-> Creating static library ..." 180 | $(QUIET) $(AR_CMD) $@ $^ 181 | 182 | $(CLI_BIN): $(STATIC_LIB) $(CLI_SRC) 183 | @echo "-> Linking executable ..." 184 | $(QUIET) $(CXX) $(CXXFLAGS) $(CLI_SRC) -o $@ $(STATIC_LIB) 185 | 186 | $(OBJ_FILES): $(OBJ_DIR)/%.o: %.cpp 187 | @echo "-> Compiling" $< "..." 188 | $(QUIET) $(MKDIR_CMD) $(dir $@) 189 | $(QUIET) $(CXX) $(CXXFLAGS) -c $< -o $@ 190 | 191 | #------------------------------------------------ 192 | # Bison rules: 193 | 194 | # Preserves the generated source files 195 | .PRECIOUS: $(GENERATED_DIR)/%.cpp 196 | 197 | $(GENERATED_DIR)/%.cpp: $(SOURCE_DIR)/%.yxx 198 | @echo "-> Running Bison for" $< "..." 199 | $(QUIET) bison -o $@ -d $< 200 | 201 | #------------------------------------------------ 202 | # Flex rules: 203 | 204 | # Preserves the generated source files 205 | .PRECIOUS: $(GENERATED_DIR)/%.cpp 206 | 207 | $(GENERATED_DIR)/%.cpp: $(SOURCE_DIR)/%.lxx 208 | @echo "-> Running Flex for" $< "..." 209 | $(QUIET) flex -t $< > $@ 210 | 211 | #------------------------------------------------ 212 | # make clean: 213 | 214 | clean: 215 | @echo "-> Cleaning ..." 216 | $(QUIET) rm -f $(CLI_BIN) $(STATIC_LIB) $(LEX_GENERATED) $(BISON_GENERATED) 217 | $(QUIET) rm -f $(addprefix test_, $(basename $(notdir $(TEST_SRC)))) 218 | $(QUIET) rm -f $(GENERATED_DIR)/*.hh $(GENERATED_DIR)/*.hpp 219 | $(QUIET) rm -rf $(OBJ_DIR) *.dSYM 220 | 221 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Moon scripting language compiler and VM 3 | 4 | [![Build Status](https://travis-ci.org/glampert/moon-lang.svg)](https://travis-ci.org/glampert/moon-lang) 5 | 6 | ![Moon Lang - a custom scripting language](https://raw.githubusercontent.com/glampert/moon-lang/master/moon-logo.png) 7 | 8 | `Moon` is a custom scripting language that borrows some of its syntax from 9 | [Lua](http://www.lua.org/) and [Rust](https://www.rust-lang.org/). 10 | 11 | This is mainly a toy/hobby project to learn more about compiler design, Virtual Machines and Interpreters. 12 | 13 | The name is just a play on the meaning of Lua (Moon in Portuguese). I chose the name on purpose 14 | to leave it clear this is a lame rip-off on the syntax of the popular scripting language. 15 | This project is not affiliated to [MoonScript](https://github.com/leafo/moonscript). 16 | 17 | ### Building 18 | 19 | To build the project on Mac and Linux, use the provided Makefile. Before building, make sure you have: 20 | 21 | - [Flex](http://flex.sourceforge.net/) version `2.6` or newer installed. 22 | - [Bison](http://www.gnu.org/software/bison/) version `3.0.4` or newer installed. 23 | - A C++11 compiler. GCC v5 or above is recommended for Linux and Clang v6 or newer for Mac OSX. 24 | 25 | To install Bison and Flex on Mac OSX, [brew](http://brew.sh/) is the tool of choice. If you experience problems 26 | with the system path, make sure to check out [this thread](http://stackoverflow.com/a/29053701/1198654). 27 | 28 | On Linux, you can use `apt` or whichever is your package manager of choice. 29 | You might need to download and build Bison yourself if a recent binary image is not available. 30 | 31 | **Building on Windows** is currently not officially supported. The source code should be fully portable, 32 | so all that should be required for a Windows build is to create a Visual Studio project. I was not able to 33 | find a binary distribution or even compilable source for the required Bison & Flex versions for Windows, 34 | so I have included the generated source files in the `generated/local/` dir. You'll be able to build on Windows 35 | without Bison & Flex, but you won't be able to generate new files if the parser or lexer are changed. 36 | 37 | ### Gallery 38 | 39 | Hello world in Moon Lang: 40 | 41 | ```rust 42 | // Once 43 | println("Hello world!"); 44 | 45 | // A few times 46 | for i in 0..5 do 47 | println(i, ": Hello world!"); 48 | end 49 | ``` 50 | 51 | Declaring variables: 52 | 53 | ```rust 54 | let i = 42; // An integer number 55 | let pi = 3.141592; // A floating-point number 56 | let s = "hello"; // A string 57 | let r = 0..10; // A range 58 | let a = ["a", "b", "c"]; // An array of strings 59 | ``` 60 | 61 | User-defined structs and enums: 62 | 63 | ```rust 64 | type Foo struct 65 | int_member: int, 66 | float_member: float, 67 | str_member: str, 68 | end 69 | 70 | // Declaring an instance of a structure: 71 | let foo = Foo{ 1, 2.2, "3" }; 72 | 73 | type Colors enum 74 | Red, 75 | Green, 76 | Blue, 77 | end 78 | 79 | // Use enum constants: 80 | let color = Colors.Blue; 81 | 82 | // Type alias: 83 | type Bar = Colors; 84 | ``` 85 | 86 | Recursive Fibonacci: 87 | 88 | ```rust 89 | func fibonacci(n: int) -> int 90 | if n <= 1 then 91 | return n; 92 | end 93 | return fibonacci(n - 1) + fibonacci(n - 2); 94 | end 95 | 96 | let fib = fibonacci(15); 97 | println("Fibonacci of 15 = ", fib); 98 | ``` 99 | 100 | Iterative Fibonacci: 101 | 102 | ```rust 103 | func fibonacci(n: int) -> int 104 | let a: int = 0; 105 | let b: int = 1; 106 | let c: int = 0; 107 | 108 | if n == 0 then 109 | return a; 110 | end 111 | 112 | let count = n + 1; 113 | for i in 2..count do 114 | c = a + b; 115 | a = b; 116 | b = c; 117 | end 118 | return b; 119 | end 120 | 121 | let fib = fibonacci(15); 122 | println("Fibonacci of 15 = ", fib); 123 | ``` 124 | 125 | C++ interface: 126 | 127 | ```cpp 128 | // Minimal sample of how to run a Moon Lang script from C++ 129 | #include "compiler.hpp" 130 | #include "vm.hpp" 131 | 132 | int main() 133 | { 134 | moon::Compiler compiler; // Script parsing and bytecode output. 135 | moon::VM vm; // Executes bytecode produced by a Moon Compiler. 136 | 137 | try 138 | { 139 | compiler.parseScript(&vm, "my_script.ml"); 140 | compiler.compile(&vm); 141 | vm.execute(); 142 | } 143 | catch (const moon::BaseException & e) 144 | { 145 | // Handle a compilation error or a runtime-error. 146 | // The exeption type will differ accordingly 147 | // (CompilerException, RuntimeException, etc). 148 | } 149 | } 150 | ``` 151 | 152 | ### License 153 | 154 | This project's source code is released under the [MIT License](http://opensource.org/licenses/MIT). 155 | 156 | -------------------------------------------------------------------------------- /generated/local/FlexLexerLocal.h: -------------------------------------------------------------------------------- 1 | // -*-C++-*- 2 | // FlexLexer.h -- define interfaces for lexical analyzer classes generated 3 | // by flex 4 | 5 | // Copyright (c) 1993 The Regents of the University of California. 6 | // All rights reserved. 7 | // 8 | // This code is derived from software contributed to Berkeley by 9 | // Kent Williams and Tom Epperly. 10 | // 11 | // Redistribution and use in source and binary forms, with or without 12 | // modification, are permitted provided that the following conditions 13 | // are met: 14 | 15 | // 1. Redistributions of source code must retain the above copyright 16 | // notice, this list of conditions and the following disclaimer. 17 | // 2. Redistributions in binary form must reproduce the above copyright 18 | // notice, this list of conditions and the following disclaimer in the 19 | // documentation and/or other materials provided with the distribution. 20 | 21 | // Neither the name of the University nor the names of its contributors 22 | // may be used to endorse or promote products derived from this software 23 | // without specific prior written permission. 24 | 25 | // THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 26 | // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 27 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | // PURPOSE. 29 | 30 | // This file defines FlexLexer, an abstract class which specifies the 31 | // external interface provided to flex C++ lexer objects, and yyFlexLexer, 32 | // which defines a particular lexer class. 33 | // 34 | // If you want to create multiple lexer classes, you use the -P flag 35 | // to rename each yyFlexLexer to some other xxFlexLexer. You then 36 | // include in your other sources once per lexer class: 37 | // 38 | // #undef yyFlexLexer 39 | // #define yyFlexLexer xxFlexLexer 40 | // #include 41 | // 42 | // #undef yyFlexLexer 43 | // #define yyFlexLexer zzFlexLexer 44 | // #include 45 | // ... 46 | 47 | #ifndef __FLEX_LEXER_H 48 | // Never included before - need to define base class. 49 | #define __FLEX_LEXER_H 50 | 51 | #include 52 | # ifndef FLEX_STD 53 | # define FLEX_STD std:: 54 | # endif 55 | 56 | extern "C++" { 57 | 58 | struct yy_buffer_state; 59 | typedef int yy_state_type; 60 | 61 | class FlexLexer { 62 | public: 63 | virtual ~FlexLexer() { } 64 | 65 | const char* YYText() const { return yytext; } 66 | int YYLeng() const { return yyleng; } 67 | 68 | virtual void 69 | yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0; 70 | virtual struct yy_buffer_state* 71 | yy_create_buffer( FLEX_STD istream* s, int size ) = 0; 72 | virtual struct yy_buffer_state* 73 | yy_create_buffer( FLEX_STD istream& s, int size ) = 0; 74 | virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0; 75 | virtual void yyrestart( FLEX_STD istream* s ) = 0; 76 | virtual void yyrestart( FLEX_STD istream& s ) = 0; 77 | 78 | virtual int yylex() = 0; 79 | 80 | // Call yylex with new input/output sources. 81 | int yylex( FLEX_STD istream& new_in, FLEX_STD ostream& new_out ) 82 | { 83 | switch_streams( new_in, new_out ); 84 | return yylex(); 85 | } 86 | 87 | int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0) 88 | { 89 | switch_streams( new_in, new_out ); 90 | return yylex(); 91 | } 92 | 93 | // Switch to new input/output streams. A nil stream pointer 94 | // indicates "keep the current one". 95 | virtual void switch_streams( FLEX_STD istream* new_in, 96 | FLEX_STD ostream* new_out ) = 0; 97 | virtual void switch_streams( FLEX_STD istream& new_in, 98 | FLEX_STD ostream& new_out ) = 0; 99 | 100 | int lineno() const { return yylineno; } 101 | 102 | int debug() const { return yy_flex_debug; } 103 | void set_debug( int flag ) { yy_flex_debug = flag; } 104 | 105 | protected: 106 | char* yytext; 107 | int yyleng; 108 | int yylineno; // only maintained if you use %option yylineno 109 | int yy_flex_debug; // only has effect with -d or "%option debug" 110 | }; 111 | 112 | } 113 | #endif // FLEXLEXER_H 114 | 115 | #if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce) 116 | // Either this is the first time through (yyFlexLexerOnce not defined), 117 | // or this is a repeated include to define a different flavor of 118 | // yyFlexLexer, as discussed in the flex manual. 119 | #define yyFlexLexerOnce 120 | 121 | extern "C++" { 122 | 123 | class yyFlexLexer : public FlexLexer { 124 | public: 125 | // arg_yyin and arg_yyout default to the cin and cout, but we 126 | // only make that assignment when initializing in yylex(). 127 | yyFlexLexer( FLEX_STD istream& arg_yyin, FLEX_STD ostream& arg_yyout ); 128 | yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 ); 129 | private: 130 | void ctor_common(); 131 | 132 | public: 133 | 134 | virtual ~yyFlexLexer(); 135 | 136 | void yy_switch_to_buffer( struct yy_buffer_state* new_buffer ); 137 | struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size ); 138 | struct yy_buffer_state* yy_create_buffer( FLEX_STD istream& s, int size ); 139 | void yy_delete_buffer( struct yy_buffer_state* b ); 140 | void yyrestart( FLEX_STD istream* s ); 141 | void yyrestart( FLEX_STD istream& s ); 142 | 143 | void yypush_buffer_state( struct yy_buffer_state* new_buffer ); 144 | void yypop_buffer_state(); 145 | 146 | virtual int yylex(); 147 | virtual void switch_streams( FLEX_STD istream& new_in, FLEX_STD ostream& new_out ); 148 | virtual void switch_streams( FLEX_STD istream* new_in = 0, FLEX_STD ostream* new_out = 0 ); 149 | virtual int yywrap(); 150 | 151 | protected: 152 | virtual int LexerInput( char* buf, int max_size ); 153 | virtual void LexerOutput( const char* buf, int size ); 154 | virtual void LexerError( const char* msg ); 155 | 156 | void yyunput( int c, char* buf_ptr ); 157 | int yyinput(); 158 | 159 | void yy_load_buffer_state(); 160 | void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream& s ); 161 | void yy_flush_buffer( struct yy_buffer_state* b ); 162 | 163 | int yy_start_stack_ptr; 164 | int yy_start_stack_depth; 165 | int* yy_start_stack; 166 | 167 | void yy_push_state( int new_state ); 168 | void yy_pop_state(); 169 | int yy_top_state(); 170 | 171 | yy_state_type yy_get_previous_state(); 172 | yy_state_type yy_try_NUL_trans( yy_state_type current_state ); 173 | int yy_get_next_buffer(); 174 | 175 | FLEX_STD istream yyin; // input source for default LexerInput 176 | FLEX_STD ostream yyout; // output sink for default LexerOutput 177 | 178 | // yy_hold_char holds the character lost when yytext is formed. 179 | char yy_hold_char; 180 | 181 | // Number of characters read into yy_ch_buf. 182 | int yy_n_chars; 183 | 184 | // Points to current character in buffer. 185 | char* yy_c_buf_p; 186 | 187 | int yy_init; // whether we need to initialize 188 | int yy_start; // start state number 189 | 190 | // Flag which is used to allow yywrap()'s to do buffer switches 191 | // instead of setting up a fresh yyin. A bit of a hack ... 192 | int yy_did_buffer_switch_on_eof; 193 | 194 | 195 | size_t yy_buffer_stack_top; /**< index of top of stack. */ 196 | size_t yy_buffer_stack_max; /**< capacity of stack. */ 197 | struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */ 198 | void yyensure_buffer_stack(void); 199 | 200 | // The following are not always needed, but may be depending 201 | // on use of certain flex features (like REJECT or yymore()). 202 | 203 | yy_state_type yy_last_accepting_state; 204 | char* yy_last_accepting_cpos; 205 | 206 | yy_state_type* yy_state_buf; 207 | yy_state_type* yy_state_ptr; 208 | 209 | char* yy_full_match; 210 | int* yy_full_state; 211 | int yy_full_lp; 212 | 213 | int yy_lp; 214 | int yy_looking_for_trail_begin; 215 | 216 | int yy_more_flag; 217 | int yy_more_len; 218 | int yy_more_offset; 219 | int yy_prev_more_offset; 220 | }; 221 | 222 | } 223 | 224 | #endif // yyFlexLexer || ! yyFlexLexerOnce 225 | 226 | -------------------------------------------------------------------------------- /generated/local/stack.hh: -------------------------------------------------------------------------------- 1 | // A Bison parser, made by GNU Bison 3.0.4. 2 | 3 | // Stack handling for Bison parsers in C++ 4 | 5 | // Copyright (C) 2002-2015 Free Software Foundation, Inc. 6 | 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | 20 | // As a special exception, you may create a larger work that contains 21 | // part or all of the Bison parser skeleton and distribute that work 22 | // under terms of your choice, so long as that work isn't itself a 23 | // parser generator using the skeleton or a modified version thereof 24 | // as a parser skeleton. Alternatively, if you modify or redistribute 25 | // the parser skeleton itself, you may (at your option) remove this 26 | // special exception, which will cause the skeleton and the resulting 27 | // Bison output files to be licensed under the GNU General Public 28 | // License without this special exception. 29 | 30 | // This special exception was added by the Free Software Foundation in 31 | // version 2.2 of Bison. 32 | 33 | /** 34 | ** \file generated/stack.hh 35 | ** Define the moon::stack class. 36 | */ 37 | 38 | #ifndef YY_YY_GENERATED_STACK_HH_INCLUDED 39 | # define YY_YY_GENERATED_STACK_HH_INCLUDED 40 | 41 | # include 42 | 43 | #line 17 "source/lib/parser.yxx" // stack.hh:151 44 | namespace moon { 45 | #line 46 "generated/stack.hh" // stack.hh:151 46 | template > 47 | class stack 48 | { 49 | public: 50 | // Hide our reversed order. 51 | typedef typename S::reverse_iterator iterator; 52 | typedef typename S::const_reverse_iterator const_iterator; 53 | 54 | stack () 55 | : seq_ () 56 | { 57 | seq_.reserve (200); 58 | } 59 | 60 | stack (unsigned int n) 61 | : seq_ (n) 62 | {} 63 | 64 | inline 65 | T& 66 | operator[] (unsigned int i) 67 | { 68 | return seq_[seq_.size () - 1 - i]; 69 | } 70 | 71 | inline 72 | const T& 73 | operator[] (unsigned int i) const 74 | { 75 | return seq_[seq_.size () - 1 - i]; 76 | } 77 | 78 | /// Steal the contents of \a t. 79 | /// 80 | /// Close to move-semantics. 81 | inline 82 | void 83 | push (T& t) 84 | { 85 | seq_.push_back (T()); 86 | operator[](0).move (t); 87 | } 88 | 89 | inline 90 | void 91 | pop (unsigned int n = 1) 92 | { 93 | for (; n; --n) 94 | seq_.pop_back (); 95 | } 96 | 97 | void 98 | clear () 99 | { 100 | seq_.clear (); 101 | } 102 | 103 | inline 104 | typename S::size_type 105 | size () const 106 | { 107 | return seq_.size (); 108 | } 109 | 110 | inline 111 | const_iterator 112 | begin () const 113 | { 114 | return seq_.rbegin (); 115 | } 116 | 117 | inline 118 | const_iterator 119 | end () const 120 | { 121 | return seq_.rend (); 122 | } 123 | 124 | private: 125 | stack (const stack&); 126 | stack& operator= (const stack&); 127 | /// The wrapped container. 128 | S seq_; 129 | }; 130 | 131 | /// Present a slice of the top of a stack. 132 | template > 133 | class slice 134 | { 135 | public: 136 | slice (const S& stack, unsigned int range) 137 | : stack_ (stack) 138 | , range_ (range) 139 | {} 140 | 141 | inline 142 | const T& 143 | operator [] (unsigned int i) const 144 | { 145 | return stack_[range_ - i]; 146 | } 147 | 148 | private: 149 | const S& stack_; 150 | unsigned int range_; 151 | }; 152 | 153 | #line 17 "source/lib/parser.yxx" // stack.hh:151 154 | } // moon 155 | #line 156 "generated/stack.hh" // stack.hh:151 156 | 157 | #endif // !YY_YY_GENERATED_STACK_HH_INCLUDED 158 | -------------------------------------------------------------------------------- /moon-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glampert/moon-lang/03fae5eb15bd3cdd05d8041303e941e810b28439/moon-logo.png -------------------------------------------------------------------------------- /source/cli/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | // ================================================================================================ 3 | // -*- C++ -*- 4 | // File: main.cpp 5 | // Author: Guilherme R. Lampert 6 | // Created on: 10/03/16 7 | // Brief: Command Line Interpreter (CLI) entry point. 8 | // ================================================================================================ 9 | 10 | #include "compiler.hpp" 11 | #include "vm.hpp" 12 | 13 | using namespace moon; 14 | 15 | struct CmdLineFlags final 16 | { 17 | // Interpreter flags: 18 | bool run = true; // 19 | bool parse = true; // -P 20 | bool compile = true; // -C 21 | bool debug = false; // -D 22 | bool warnings = false; // -W 23 | bool verbose = false; // -V 24 | 25 | // Debug visualization flags: 26 | bool dumpSymbols = false; // -dump=symbols 27 | bool dumpSyntax = false; // -dump=syntax 28 | bool dumpFuncs = false; // -dump=funcs 29 | bool dumpTypes = false; // -dump=types 30 | bool dumpGCObjs = false; // -dump=gc 31 | bool dumpIntermediateCode = false; // -dump=intrcode 32 | bool dumpVMBytecode = false; // -dump=bytecode 33 | bool dumpGlobalData = false; // -dump=globdata 34 | 35 | void print(std::ostream & os) const 36 | { 37 | os << "Moon: Command line flags:\n"; 38 | if (parse && !run) { os << "-P\n"; } 39 | if (compile && !run) { os << "-C\n"; } 40 | if (debug) { os << "-D\n"; } 41 | if (warnings) { os << "-W\n"; } 42 | if (verbose) { os << "-V\n"; } 43 | if (dumpSymbols) { os << "-dump=symbols\n"; } 44 | if (dumpSyntax) { os << "-dump=syntax\n"; } 45 | if (dumpFuncs) { os << "-dump=funcs\n"; } 46 | if (dumpTypes) { os << "-dump=types\n"; } 47 | if (dumpGCObjs) { os << "-dump=gc\n"; } 48 | if (dumpIntermediateCode) { os << "-dump=intrcode\n"; } 49 | if (dumpVMBytecode) { os << "-dump=bytecode\n"; } 50 | if (dumpGlobalData) { os << "-dump=globdata\n"; } 51 | os << "\n"; 52 | } 53 | }; 54 | 55 | static void printUsage(const char * const progName, std::ostream & os) 56 | { 57 | os << "usage:\n" 58 | << " $ " << progName << "