Browse Source

Removed outdated projects folder. Added new optionals folder and new Math class. Update Xcode, Makefile and CMakeLists.

Marco Bambini 8 years ago
parent
commit
72c66a229a
45 changed files with 797 additions and 3023 deletions
  1. 4 2
      CMakeLists.txt
  2. 4 2
      Makefile
  3. 0 33
      gravity.sln
  4. 18 0
      gravity.xcodeproj/project.pbxproj
  5. 0 527
      projects/Butterfly/Butterfly.xcodeproj/project.pbxproj
  6. 0 15
      projects/Butterfly/Butterfly/AppDelegate.h
  7. 0 103
      projects/Butterfly/Butterfly/AppDelegate.m
  8. 0 58
      projects/Butterfly/Butterfly/Assets.xcassets/AppIcon.appiconset/Contents.json
  9. 0 703
      projects/Butterfly/Butterfly/Base.lproj/MainMenu.xib
  10. 0 32
      projects/Butterfly/Butterfly/Info.plist
  11. 0 33
      projects/Butterfly/Butterfly/Sources/BTFCodeEditor.h
  12. 0 286
      projects/Butterfly/Butterfly/Sources/BTFCodeEditor.m
  13. 0 16
      projects/Butterfly/Butterfly/Sources/BTFDelegate.h
  14. 0 25
      projects/Butterfly/Butterfly/Sources/BTFPopover.h
  15. 0 95
      projects/Butterfly/Butterfly/Sources/BTFPopover.m
  16. 0 18
      projects/Butterfly/Butterfly/Sources/BTFPopoverFrame.h
  17. 0 25
      projects/Butterfly/Butterfly/Sources/BTFPopoverFrame.m
  18. 0 13
      projects/Butterfly/Butterfly/Sources/BTFPopoverWindow.h
  19. 0 38
      projects/Butterfly/Butterfly/Sources/BTFPopoverWindow.m
  20. 0 21
      projects/Butterfly/Butterfly/Sources/BTFRulerView.h
  21. 0 150
      projects/Butterfly/Butterfly/Sources/BTFRulerView.m
  22. 0 17
      projects/Butterfly/Butterfly/Sources/BTFTextView.h
  23. 0 526
      projects/Butterfly/Butterfly/Sources/BTFTextView.m
  24. 0 54
      projects/Butterfly/Butterfly/Sources/BTFThemeKeys.h
  25. 0 13
      projects/Butterfly/Butterfly/main.m
  26. 0 36
      projects/Butterfly/Themes/Fourier.theme
  27. 0 34
      projects/Butterfly/Themes/Gauss.theme
  28. 0 36
      projects/Butterfly/Themes/Laplace.theme
  29. 0 34
      projects/Butterfly/Themes/Riemann.theme
  30. BIN
      projects/Butterfly/screenshot.png
  31. 0 11
      projects/README.md
  32. 2 0
      src/cli/gravity.c
  33. 1 0
      src/compiler/gravity_codegen.c
  34. 4 1
      src/compiler/gravity_compiler.c
  35. 17 1
      src/compiler/gravity_parser.c
  36. 0 0
      src/optionals/README.md
  37. 616 0
      src/optionals/gravity_math.c
  38. 19 0
      src/optionals/gravity_math.h
  39. 29 0
      src/optionals/gravity_optionals.h
  40. 16 62
      src/runtime/gravity_core.c
  41. 4 0
      src/runtime/gravity_core.h
  42. 16 0
      src/runtime/gravity_vm.c
  43. 3 0
      src/runtime/gravity_vm.h
  44. 36 0
      src/runtime/gravity_vmmacros.h
  45. 8 3
      src/shared/gravity_value.c

+ 4 - 2
CMakeLists.txt

@@ -4,6 +4,7 @@ SET(COMPILER_DIR src/compiler/)
 SET(RUNTIME_DIR src/runtime/)
 SET(RUNTIME_DIR src/runtime/)
 SET(SHARED_DIR src/shared/)
 SET(SHARED_DIR src/shared/)
 SET(UTILS_DIR src/utils/)
 SET(UTILS_DIR src/utils/)
+SET(OPT_DIR src/optionals/)
 
 
 SET(UNITTEST_SRC src/cli/unittest.c)
 SET(UNITTEST_SRC src/cli/unittest.c)
 SET(GRAVITY_SRC src/cli/gravity.c)
 SET(GRAVITY_SRC src/cli/gravity.c)
@@ -12,12 +13,13 @@ AUX_SOURCE_DIRECTORY(${COMPILER_DIR} COMPILER_FILES)
 AUX_SOURCE_DIRECTORY(${RUNTIME_DIR} RUNTIME_FILES)
 AUX_SOURCE_DIRECTORY(${RUNTIME_DIR} RUNTIME_FILES)
 AUX_SOURCE_DIRECTORY(${SHARED_DIR} SHARED_FILES)
 AUX_SOURCE_DIRECTORY(${SHARED_DIR} SHARED_FILES)
 AUX_SOURCE_DIRECTORY(${UTILS_DIR} UTILS_FILES)
 AUX_SOURCE_DIRECTORY(${UTILS_DIR} UTILS_FILES)
+AUX_SOURCE_DIRECTORY(${OPT_DIR} OPT_FILES)
 
 
-include_directories(${COMPILER_DIR} ${RUNTIME_DIR} ${SHARED_DIR} ${UTILS_DIR})
+include_directories(${COMPILER_DIR} ${RUNTIME_DIR} ${SHARED_DIR} ${UTILS_DIR} ${OPT_DIR})
 
 
 SET(CMAKE_C_STANDARD 11)
 SET(CMAKE_C_STANDARD 11)
 
 
-SET(SRC_FILES ${COMPILER_FILES} ${RUNTIME_FILES} ${SHARED_FILES} ${UTILS_FILES})
+SET(SRC_FILES ${COMPILER_FILES} ${RUNTIME_FILES} ${SHARED_FILES} ${UTILS_FILES} ${OPT_FILES})
 
 
 ADD_LIBRARY(libgravity OBJECT ${SRC_FILES})
 ADD_LIBRARY(libgravity OBJECT ${SRC_FILES})
 
 

+ 4 - 2
Makefile

@@ -2,15 +2,17 @@ COMPILER_DIR = src/compiler/
 RUNTIME_DIR = src/runtime/
 RUNTIME_DIR = src/runtime/
 SHARED_DIR = src/shared/
 SHARED_DIR = src/shared/
 UTILS_DIR = src/utils/
 UTILS_DIR = src/utils/
+OPT_DIR = src/optionals/
 UNITTEST_SRC = src/cli/unittest.c
 UNITTEST_SRC = src/cli/unittest.c
 GRAVITY_SRC = src/cli/gravity.c
 GRAVITY_SRC = src/cli/gravity.c
 
 
 SRC = $(wildcard $(COMPILER_DIR)*.c) \
 SRC = $(wildcard $(COMPILER_DIR)*.c) \
       $(wildcard $(RUNTIME_DIR)/*.c) \
       $(wildcard $(RUNTIME_DIR)/*.c) \
       $(wildcard $(SHARED_DIR)/*.c) \
       $(wildcard $(SHARED_DIR)/*.c) \
-      $(wildcard $(UTILS_DIR)/*.c)
+      $(wildcard $(UTILS_DIR)/*.c) \
+      $(wildcard $(OPT_DIR)/*.c)
 
 
-INCLUDE = -I$(COMPILER_DIR) -I$(RUNTIME_DIR) -I$(SHARED_DIR) -I$(UTILS_DIR)
+INCLUDE = -I$(COMPILER_DIR) -I$(RUNTIME_DIR) -I$(SHARED_DIR) -I$(UTILS_DIR) -I$(OPT_DIR)
 CFLAGS = $(INCLUDE) -O2 -std=gnu99 -fgnu89-inline -fPIC -DBUILD_GRAVITY_API
 CFLAGS = $(INCLUDE) -O2 -std=gnu99 -fgnu89-inline -fPIC -DBUILD_GRAVITY_API
 OBJ = $(SRC:.c=.o)
 OBJ = $(SRC:.c=.o)
 
 

+ 0 - 33
gravity.sln

@@ -1,33 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.26127.0
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GravityLang", "gravity_visualstudio\gravity.vcxproj", "{EC12BE0A-025E-4168-9D2D-419A18CB2EF5}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{23D9D4FA-6B0F-4151-9CD6-C56F0C44F646}"
-	ProjectSection(SolutionItems) = preProject
-		exports.def = exports.def
-	EndProjectSection
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|x64 = Debug|x64
-		Debug|x86 = Debug|x86
-		Release|x64 = Release|x64
-		Release|x86 = Release|x86
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{EC12BE0A-025E-4168-9D2D-419A18CB2EF5}.Debug|x64.ActiveCfg = Debug|x64
-		{EC12BE0A-025E-4168-9D2D-419A18CB2EF5}.Debug|x64.Build.0 = Debug|x64
-		{EC12BE0A-025E-4168-9D2D-419A18CB2EF5}.Debug|x86.ActiveCfg = Debug|Win32
-		{EC12BE0A-025E-4168-9D2D-419A18CB2EF5}.Debug|x86.Build.0 = Debug|Win32
-		{EC12BE0A-025E-4168-9D2D-419A18CB2EF5}.Release|x64.ActiveCfg = Release|x64
-		{EC12BE0A-025E-4168-9D2D-419A18CB2EF5}.Release|x64.Build.0 = Release|x64
-		{EC12BE0A-025E-4168-9D2D-419A18CB2EF5}.Release|x86.ActiveCfg = Release|Win32
-		{EC12BE0A-025E-4168-9D2D-419A18CB2EF5}.Release|x86.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal

+ 18 - 0
gravity.xcodeproj/project.pbxproj

@@ -49,6 +49,8 @@
 		A9506D5F1E69AB8E009A0045 /* gravity_debug.c in Sources */ = {isa = PBXBuildFile; fileRef = A9506D2A1E69AB1E009A0045 /* gravity_debug.c */; };
 		A9506D5F1E69AB8E009A0045 /* gravity_debug.c in Sources */ = {isa = PBXBuildFile; fileRef = A9506D2A1E69AB1E009A0045 /* gravity_debug.c */; };
 		A9506D601E69AB8E009A0045 /* gravity_json.c in Sources */ = {isa = PBXBuildFile; fileRef = A9506D2C1E69AB1E009A0045 /* gravity_json.c */; };
 		A9506D601E69AB8E009A0045 /* gravity_json.c in Sources */ = {isa = PBXBuildFile; fileRef = A9506D2C1E69AB1E009A0045 /* gravity_json.c */; };
 		A9506D611E69AB8E009A0045 /* gravity_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = A9506D2E1E69AB1E009A0045 /* gravity_utils.c */; };
 		A9506D611E69AB8E009A0045 /* gravity_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = A9506D2E1E69AB1E009A0045 /* gravity_utils.c */; };
+		A9BB72F01F470832002FD2D6 /* gravity_math.c in Sources */ = {isa = PBXBuildFile; fileRef = A9BB72EC1F470832002FD2D6 /* gravity_math.c */; };
+		A9BB72F21F470888002FD2D6 /* gravity_math.c in Sources */ = {isa = PBXBuildFile; fileRef = A9BB72EC1F470832002FD2D6 /* gravity_math.c */; };
 /* End PBXBuildFile section */
 /* End PBXBuildFile section */
 
 
 /* Begin PBXCopyFilesBuildPhase section */
 /* Begin PBXCopyFilesBuildPhase section */
@@ -123,6 +125,9 @@
 		A9506D2E1E69AB1E009A0045 /* gravity_utils.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = gravity_utils.c; sourceTree = "<group>"; };
 		A9506D2E1E69AB1E009A0045 /* gravity_utils.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = gravity_utils.c; sourceTree = "<group>"; };
 		A9506D2F1E69AB1E009A0045 /* gravity_utils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = gravity_utils.h; sourceTree = "<group>"; };
 		A9506D2F1E69AB1E009A0045 /* gravity_utils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = gravity_utils.h; sourceTree = "<group>"; };
 		A9506D371E69AB33009A0045 /* unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = unittest; sourceTree = BUILT_PRODUCTS_DIR; };
 		A9506D371E69AB33009A0045 /* unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = unittest; sourceTree = BUILT_PRODUCTS_DIR; };
+		A9BB72EC1F470832002FD2D6 /* gravity_math.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_math.c; sourceTree = "<group>"; };
+		A9BB72ED1F470832002FD2D6 /* gravity_math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_math.h; sourceTree = "<group>"; };
+		A9BB72EE1F470832002FD2D6 /* gravity_optionals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_optionals.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 /* End PBXFileReference section */
 
 
 /* Begin PBXFrameworksBuildPhase section */
 /* Begin PBXFrameworksBuildPhase section */
@@ -168,6 +173,7 @@
 				A9506D181E69AB1E009A0045 /* runtime */,
 				A9506D181E69AB1E009A0045 /* runtime */,
 				A9506D1E1E69AB1E009A0045 /* shared */,
 				A9506D1E1E69AB1E009A0045 /* shared */,
 				A9506D291E69AB1E009A0045 /* utils */,
 				A9506D291E69AB1E009A0045 /* utils */,
+				A9BB72EB1F470832002FD2D6 /* optionals */,
 			);
 			);
 			name = gravity;
 			name = gravity;
 			path = src;
 			path = src;
@@ -256,6 +262,16 @@
 			path = utils;
 			path = utils;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		A9BB72EB1F470832002FD2D6 /* optionals */ = {
+			isa = PBXGroup;
+			children = (
+				A9BB72EC1F470832002FD2D6 /* gravity_math.c */,
+				A9BB72ED1F470832002FD2D6 /* gravity_math.h */,
+				A9BB72EE1F470832002FD2D6 /* gravity_optionals.h */,
+			);
+			path = optionals;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 /* End PBXGroup section */
 
 
 /* Begin PBXNativeTarget section */
 /* Begin PBXNativeTarget section */
@@ -347,6 +363,7 @@
 				A9506D421E69AB78009A0045 /* gravity_semacheck2.c in Sources */,
 				A9506D421E69AB78009A0045 /* gravity_semacheck2.c in Sources */,
 				A9506D3E1E69AB78009A0045 /* gravity_lexer.c in Sources */,
 				A9506D3E1E69AB78009A0045 /* gravity_lexer.c in Sources */,
 				A9506D431E69AB78009A0045 /* gravity_symboltable.c in Sources */,
 				A9506D431E69AB78009A0045 /* gravity_symboltable.c in Sources */,
+				A9BB72F01F470832002FD2D6 /* gravity_math.c in Sources */,
 				A9506D3A1E69AB78009A0045 /* gravity_ast.c in Sources */,
 				A9506D3A1E69AB78009A0045 /* gravity_ast.c in Sources */,
 				A9506D5E1E69AB8D009A0045 /* gravity_utils.c in Sources */,
 				A9506D5E1E69AB8D009A0045 /* gravity_utils.c in Sources */,
 				A9506D451E69AB78009A0045 /* gravity_visitor.c in Sources */,
 				A9506D451E69AB78009A0045 /* gravity_visitor.c in Sources */,
@@ -375,6 +392,7 @@
 				A9506D4E1E69AB78009A0045 /* gravity_semacheck2.c in Sources */,
 				A9506D4E1E69AB78009A0045 /* gravity_semacheck2.c in Sources */,
 				A9506D4A1E69AB78009A0045 /* gravity_lexer.c in Sources */,
 				A9506D4A1E69AB78009A0045 /* gravity_lexer.c in Sources */,
 				A9506D4F1E69AB78009A0045 /* gravity_symboltable.c in Sources */,
 				A9506D4F1E69AB78009A0045 /* gravity_symboltable.c in Sources */,
+				A9BB72F21F470888002FD2D6 /* gravity_math.c in Sources */,
 				A9506D461E69AB78009A0045 /* gravity_ast.c in Sources */,
 				A9506D461E69AB78009A0045 /* gravity_ast.c in Sources */,
 				A9506D611E69AB8E009A0045 /* gravity_utils.c in Sources */,
 				A9506D611E69AB8E009A0045 /* gravity_utils.c in Sources */,
 				A9506D511E69AB78009A0045 /* gravity_visitor.c in Sources */,
 				A9506D511E69AB78009A0045 /* gravity_visitor.c in Sources */,

+ 0 - 527
projects/Butterfly/Butterfly.xcodeproj/project.pbxproj

@@ -1,527 +0,0 @@
-// !$*UTF8*$!
-{
-	archiveVersion = 1;
-	classes = {
-	};
-	objectVersion = 46;
-	objects = {
-
-/* Begin PBXBuildFile section */
-		A96F4EAB1E7D8638000509B3 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EAA1E7D8638000509B3 /* AppDelegate.m */; };
-		A96F4EAE1E7D8638000509B3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EAD1E7D8638000509B3 /* main.m */; };
-		A96F4EB01E7D8638000509B3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A96F4EAF1E7D8638000509B3 /* Assets.xcassets */; };
-		A96F4EB31E7D8638000509B3 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = A96F4EB11E7D8638000509B3 /* MainMenu.xib */; };
-		A96F4EBB1E7D8696000509B3 /* Themes in Resources */ = {isa = PBXBuildFile; fileRef = A96F4EBA1E7D8696000509B3 /* Themes */; };
-		A96F4EEF1E7D86D8000509B3 /* gravity_ast.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EBF1E7D86D8000509B3 /* gravity_ast.c */; };
-		A96F4EF01E7D86D8000509B3 /* gravity_codegen.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EC11E7D86D8000509B3 /* gravity_codegen.c */; };
-		A96F4EF11E7D86D8000509B3 /* gravity_compiler.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EC31E7D86D8000509B3 /* gravity_compiler.c */; };
-		A96F4EF21E7D86D8000509B3 /* gravity_ircode.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EC51E7D86D8000509B3 /* gravity_ircode.c */; };
-		A96F4EF31E7D86D8000509B3 /* gravity_lexer.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EC71E7D86D8000509B3 /* gravity_lexer.c */; };
-		A96F4EF41E7D86D8000509B3 /* gravity_optimizer.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EC91E7D86D8000509B3 /* gravity_optimizer.c */; };
-		A96F4EF51E7D86D8000509B3 /* gravity_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4ECB1E7D86D8000509B3 /* gravity_parser.c */; };
-		A96F4EF61E7D86D8000509B3 /* gravity_semacheck1.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4ECD1E7D86D8000509B3 /* gravity_semacheck1.c */; };
-		A96F4EF71E7D86D8000509B3 /* gravity_semacheck2.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4ECF1E7D86D8000509B3 /* gravity_semacheck2.c */; };
-		A96F4EF81E7D86D8000509B3 /* gravity_symboltable.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4ED11E7D86D8000509B3 /* gravity_symboltable.c */; };
-		A96F4EF91E7D86D8000509B3 /* gravity_token.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4ED31E7D86D8000509B3 /* gravity_token.c */; };
-		A96F4EFA1E7D86D8000509B3 /* gravity_visitor.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4ED51E7D86D8000509B3 /* gravity_visitor.c */; };
-		A96F4EFB1E7D86D8000509B3 /* gravity_core.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4ED81E7D86D8000509B3 /* gravity_core.c */; };
-		A96F4EFC1E7D86D8000509B3 /* gravity_vm.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EDA1E7D86D8000509B3 /* gravity_vm.c */; };
-		A96F4EFD1E7D86D8000509B3 /* gravity_hash.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EE01E7D86D8000509B3 /* gravity_hash.c */; };
-		A96F4EFE1E7D86D8000509B3 /* gravity_memory.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EE31E7D86D8000509B3 /* gravity_memory.c */; };
-		A96F4EFF1E7D86D8000509B3 /* gravity_value.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EE61E7D86D8000509B3 /* gravity_value.c */; };
-		A96F4F001E7D86D8000509B3 /* gravity_debug.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EE91E7D86D8000509B3 /* gravity_debug.c */; };
-		A96F4F011E7D86D8000509B3 /* gravity_json.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EEB1E7D86D8000509B3 /* gravity_json.c */; };
-		A96F4F021E7D86D8000509B3 /* gravity_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = A96F4EED1E7D86D8000509B3 /* gravity_utils.c */; };
-		A96F4F121E7D8706000509B3 /* BTFCodeEditor.m in Sources */ = {isa = PBXBuildFile; fileRef = A96F4F051E7D8706000509B3 /* BTFCodeEditor.m */; };
-		A96F4F131E7D8706000509B3 /* BTFPopover.m in Sources */ = {isa = PBXBuildFile; fileRef = A96F4F081E7D8706000509B3 /* BTFPopover.m */; };
-		A96F4F141E7D8706000509B3 /* BTFPopoverFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = A96F4F0A1E7D8706000509B3 /* BTFPopoverFrame.m */; };
-		A96F4F151E7D8706000509B3 /* BTFPopoverWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A96F4F0C1E7D8706000509B3 /* BTFPopoverWindow.m */; };
-		A96F4F161E7D8706000509B3 /* BTFRulerView.m in Sources */ = {isa = PBXBuildFile; fileRef = A96F4F0E1E7D8706000509B3 /* BTFRulerView.m */; };
-		A96F4F171E7D8706000509B3 /* BTFTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = A96F4F101E7D8706000509B3 /* BTFTextView.m */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
-		A96F4EA61E7D8638000509B3 /* Butterfly.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Butterfly.app; sourceTree = BUILT_PRODUCTS_DIR; };
-		A96F4EA91E7D8638000509B3 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
-		A96F4EAA1E7D8638000509B3 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
-		A96F4EAD1E7D8638000509B3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
-		A96F4EAF1E7D8638000509B3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
-		A96F4EB21E7D8638000509B3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
-		A96F4EB41E7D8638000509B3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
-		A96F4EBA1E7D8696000509B3 /* Themes */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Themes; sourceTree = SOURCE_ROOT; };
-		A96F4EBE1E7D86D8000509B3 /* debug_macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_macros.h; sourceTree = "<group>"; };
-		A96F4EBF1E7D86D8000509B3 /* gravity_ast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_ast.c; sourceTree = "<group>"; };
-		A96F4EC01E7D86D8000509B3 /* gravity_ast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_ast.h; sourceTree = "<group>"; };
-		A96F4EC11E7D86D8000509B3 /* gravity_codegen.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_codegen.c; sourceTree = "<group>"; };
-		A96F4EC21E7D86D8000509B3 /* gravity_codegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_codegen.h; sourceTree = "<group>"; };
-		A96F4EC31E7D86D8000509B3 /* gravity_compiler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_compiler.c; sourceTree = "<group>"; };
-		A96F4EC41E7D86D8000509B3 /* gravity_compiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_compiler.h; sourceTree = "<group>"; };
-		A96F4EC51E7D86D8000509B3 /* gravity_ircode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_ircode.c; sourceTree = "<group>"; };
-		A96F4EC61E7D86D8000509B3 /* gravity_ircode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_ircode.h; sourceTree = "<group>"; };
-		A96F4EC71E7D86D8000509B3 /* gravity_lexer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_lexer.c; sourceTree = "<group>"; };
-		A96F4EC81E7D86D8000509B3 /* gravity_lexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_lexer.h; sourceTree = "<group>"; };
-		A96F4EC91E7D86D8000509B3 /* gravity_optimizer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_optimizer.c; sourceTree = "<group>"; };
-		A96F4ECA1E7D86D8000509B3 /* gravity_optimizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_optimizer.h; sourceTree = "<group>"; };
-		A96F4ECB1E7D86D8000509B3 /* gravity_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_parser.c; sourceTree = "<group>"; };
-		A96F4ECC1E7D86D8000509B3 /* gravity_parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_parser.h; sourceTree = "<group>"; };
-		A96F4ECD1E7D86D8000509B3 /* gravity_semacheck1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_semacheck1.c; sourceTree = "<group>"; };
-		A96F4ECE1E7D86D8000509B3 /* gravity_semacheck1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_semacheck1.h; sourceTree = "<group>"; };
-		A96F4ECF1E7D86D8000509B3 /* gravity_semacheck2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_semacheck2.c; sourceTree = "<group>"; };
-		A96F4ED01E7D86D8000509B3 /* gravity_semacheck2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_semacheck2.h; sourceTree = "<group>"; };
-		A96F4ED11E7D86D8000509B3 /* gravity_symboltable.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_symboltable.c; sourceTree = "<group>"; };
-		A96F4ED21E7D86D8000509B3 /* gravity_symboltable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_symboltable.h; sourceTree = "<group>"; };
-		A96F4ED31E7D86D8000509B3 /* gravity_token.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_token.c; sourceTree = "<group>"; };
-		A96F4ED41E7D86D8000509B3 /* gravity_token.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_token.h; sourceTree = "<group>"; };
-		A96F4ED51E7D86D8000509B3 /* gravity_visitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_visitor.c; sourceTree = "<group>"; };
-		A96F4ED61E7D86D8000509B3 /* gravity_visitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_visitor.h; sourceTree = "<group>"; };
-		A96F4ED81E7D86D8000509B3 /* gravity_core.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_core.c; sourceTree = "<group>"; };
-		A96F4ED91E7D86D8000509B3 /* gravity_core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_core.h; sourceTree = "<group>"; };
-		A96F4EDA1E7D86D8000509B3 /* gravity_vm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_vm.c; sourceTree = "<group>"; };
-		A96F4EDB1E7D86D8000509B3 /* gravity_vm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_vm.h; sourceTree = "<group>"; };
-		A96F4EDC1E7D86D8000509B3 /* gravity_vmmacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_vmmacros.h; sourceTree = "<group>"; };
-		A96F4EDE1E7D86D8000509B3 /* gravity_array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_array.h; sourceTree = "<group>"; };
-		A96F4EDF1E7D86D8000509B3 /* gravity_delegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_delegate.h; sourceTree = "<group>"; };
-		A96F4EE01E7D86D8000509B3 /* gravity_hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_hash.c; sourceTree = "<group>"; };
-		A96F4EE11E7D86D8000509B3 /* gravity_hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_hash.h; sourceTree = "<group>"; };
-		A96F4EE21E7D86D8000509B3 /* gravity_macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_macros.h; sourceTree = "<group>"; };
-		A96F4EE31E7D86D8000509B3 /* gravity_memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_memory.c; sourceTree = "<group>"; };
-		A96F4EE41E7D86D8000509B3 /* gravity_memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_memory.h; sourceTree = "<group>"; };
-		A96F4EE51E7D86D8000509B3 /* gravity_opcodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_opcodes.h; sourceTree = "<group>"; };
-		A96F4EE61E7D86D8000509B3 /* gravity_value.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_value.c; sourceTree = "<group>"; };
-		A96F4EE71E7D86D8000509B3 /* gravity_value.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_value.h; sourceTree = "<group>"; };
-		A96F4EE91E7D86D8000509B3 /* gravity_debug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_debug.c; sourceTree = "<group>"; };
-		A96F4EEA1E7D86D8000509B3 /* gravity_debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_debug.h; sourceTree = "<group>"; };
-		A96F4EEB1E7D86D8000509B3 /* gravity_json.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_json.c; sourceTree = "<group>"; };
-		A96F4EEC1E7D86D8000509B3 /* gravity_json.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_json.h; sourceTree = "<group>"; };
-		A96F4EED1E7D86D8000509B3 /* gravity_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gravity_utils.c; sourceTree = "<group>"; };
-		A96F4EEE1E7D86D8000509B3 /* gravity_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gravity_utils.h; sourceTree = "<group>"; };
-		A96F4F041E7D8706000509B3 /* BTFCodeEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTFCodeEditor.h; sourceTree = "<group>"; };
-		A96F4F051E7D8706000509B3 /* BTFCodeEditor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTFCodeEditor.m; sourceTree = "<group>"; };
-		A96F4F061E7D8706000509B3 /* BTFDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTFDelegate.h; sourceTree = "<group>"; };
-		A96F4F071E7D8706000509B3 /* BTFPopover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTFPopover.h; sourceTree = "<group>"; };
-		A96F4F081E7D8706000509B3 /* BTFPopover.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTFPopover.m; sourceTree = "<group>"; };
-		A96F4F091E7D8706000509B3 /* BTFPopoverFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTFPopoverFrame.h; sourceTree = "<group>"; };
-		A96F4F0A1E7D8706000509B3 /* BTFPopoverFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTFPopoverFrame.m; sourceTree = "<group>"; };
-		A96F4F0B1E7D8706000509B3 /* BTFPopoverWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTFPopoverWindow.h; sourceTree = "<group>"; };
-		A96F4F0C1E7D8706000509B3 /* BTFPopoverWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTFPopoverWindow.m; sourceTree = "<group>"; };
-		A96F4F0D1E7D8706000509B3 /* BTFRulerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTFRulerView.h; sourceTree = "<group>"; };
-		A96F4F0E1E7D8706000509B3 /* BTFRulerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTFRulerView.m; sourceTree = "<group>"; };
-		A96F4F0F1E7D8706000509B3 /* BTFTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTFTextView.h; sourceTree = "<group>"; };
-		A96F4F101E7D8706000509B3 /* BTFTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTFTextView.m; sourceTree = "<group>"; };
-		A96F4F111E7D8706000509B3 /* BTFThemeKeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTFThemeKeys.h; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
-		A96F4EA31E7D8638000509B3 /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
-		A96F4E9D1E7D8638000509B3 = {
-			isa = PBXGroup;
-			children = (
-				A96F4EA81E7D8638000509B3 /* Main */,
-				A96F4F031E7D8706000509B3 /* Sources */,
-				A96F4EBC1E7D86BA000509B3 /* Gravity */,
-				A96F4EA71E7D8638000509B3 /* Products */,
-			);
-			sourceTree = "<group>";
-		};
-		A96F4EA71E7D8638000509B3 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				A96F4EA61E7D8638000509B3 /* Butterfly.app */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
-		A96F4EA81E7D8638000509B3 /* Main */ = {
-			isa = PBXGroup;
-			children = (
-				A96F4EA91E7D8638000509B3 /* AppDelegate.h */,
-				A96F4EAA1E7D8638000509B3 /* AppDelegate.m */,
-				A96F4EB11E7D8638000509B3 /* MainMenu.xib */,
-				A96F4EAC1E7D8638000509B3 /* Supporting Files */,
-			);
-			name = Main;
-			path = Butterfly;
-			sourceTree = "<group>";
-		};
-		A96F4EAC1E7D8638000509B3 /* Supporting Files */ = {
-			isa = PBXGroup;
-			children = (
-				A96F4EBA1E7D8696000509B3 /* Themes */,
-				A96F4EAF1E7D8638000509B3 /* Assets.xcassets */,
-				A96F4EB41E7D8638000509B3 /* Info.plist */,
-				A96F4EAD1E7D8638000509B3 /* main.m */,
-			);
-			name = "Supporting Files";
-			sourceTree = "<group>";
-		};
-		A96F4EBC1E7D86BA000509B3 /* Gravity */ = {
-			isa = PBXGroup;
-			children = (
-				A96F4EBD1E7D86D8000509B3 /* compiler */,
-				A96F4ED71E7D86D8000509B3 /* runtime */,
-				A96F4EDD1E7D86D8000509B3 /* shared */,
-				A96F4EE81E7D86D8000509B3 /* utils */,
-			);
-			name = Gravity;
-			sourceTree = "<group>";
-		};
-		A96F4EBD1E7D86D8000509B3 /* compiler */ = {
-			isa = PBXGroup;
-			children = (
-				A96F4EBE1E7D86D8000509B3 /* debug_macros.h */,
-				A96F4EBF1E7D86D8000509B3 /* gravity_ast.c */,
-				A96F4EC01E7D86D8000509B3 /* gravity_ast.h */,
-				A96F4EC11E7D86D8000509B3 /* gravity_codegen.c */,
-				A96F4EC21E7D86D8000509B3 /* gravity_codegen.h */,
-				A96F4EC31E7D86D8000509B3 /* gravity_compiler.c */,
-				A96F4EC41E7D86D8000509B3 /* gravity_compiler.h */,
-				A96F4EC51E7D86D8000509B3 /* gravity_ircode.c */,
-				A96F4EC61E7D86D8000509B3 /* gravity_ircode.h */,
-				A96F4EC71E7D86D8000509B3 /* gravity_lexer.c */,
-				A96F4EC81E7D86D8000509B3 /* gravity_lexer.h */,
-				A96F4EC91E7D86D8000509B3 /* gravity_optimizer.c */,
-				A96F4ECA1E7D86D8000509B3 /* gravity_optimizer.h */,
-				A96F4ECB1E7D86D8000509B3 /* gravity_parser.c */,
-				A96F4ECC1E7D86D8000509B3 /* gravity_parser.h */,
-				A96F4ECD1E7D86D8000509B3 /* gravity_semacheck1.c */,
-				A96F4ECE1E7D86D8000509B3 /* gravity_semacheck1.h */,
-				A96F4ECF1E7D86D8000509B3 /* gravity_semacheck2.c */,
-				A96F4ED01E7D86D8000509B3 /* gravity_semacheck2.h */,
-				A96F4ED11E7D86D8000509B3 /* gravity_symboltable.c */,
-				A96F4ED21E7D86D8000509B3 /* gravity_symboltable.h */,
-				A96F4ED31E7D86D8000509B3 /* gravity_token.c */,
-				A96F4ED41E7D86D8000509B3 /* gravity_token.h */,
-				A96F4ED51E7D86D8000509B3 /* gravity_visitor.c */,
-				A96F4ED61E7D86D8000509B3 /* gravity_visitor.h */,
-			);
-			name = compiler;
-			path = ../../src/compiler;
-			sourceTree = "<group>";
-		};
-		A96F4ED71E7D86D8000509B3 /* runtime */ = {
-			isa = PBXGroup;
-			children = (
-				A96F4ED81E7D86D8000509B3 /* gravity_core.c */,
-				A96F4ED91E7D86D8000509B3 /* gravity_core.h */,
-				A96F4EDA1E7D86D8000509B3 /* gravity_vm.c */,
-				A96F4EDB1E7D86D8000509B3 /* gravity_vm.h */,
-				A96F4EDC1E7D86D8000509B3 /* gravity_vmmacros.h */,
-			);
-			name = runtime;
-			path = ../../src/runtime;
-			sourceTree = "<group>";
-		};
-		A96F4EDD1E7D86D8000509B3 /* shared */ = {
-			isa = PBXGroup;
-			children = (
-				A96F4EDE1E7D86D8000509B3 /* gravity_array.h */,
-				A96F4EDF1E7D86D8000509B3 /* gravity_delegate.h */,
-				A96F4EE01E7D86D8000509B3 /* gravity_hash.c */,
-				A96F4EE11E7D86D8000509B3 /* gravity_hash.h */,
-				A96F4EE21E7D86D8000509B3 /* gravity_macros.h */,
-				A96F4EE31E7D86D8000509B3 /* gravity_memory.c */,
-				A96F4EE41E7D86D8000509B3 /* gravity_memory.h */,
-				A96F4EE51E7D86D8000509B3 /* gravity_opcodes.h */,
-				A96F4EE61E7D86D8000509B3 /* gravity_value.c */,
-				A96F4EE71E7D86D8000509B3 /* gravity_value.h */,
-			);
-			name = shared;
-			path = ../../src/shared;
-			sourceTree = "<group>";
-		};
-		A96F4EE81E7D86D8000509B3 /* utils */ = {
-			isa = PBXGroup;
-			children = (
-				A96F4EE91E7D86D8000509B3 /* gravity_debug.c */,
-				A96F4EEA1E7D86D8000509B3 /* gravity_debug.h */,
-				A96F4EEB1E7D86D8000509B3 /* gravity_json.c */,
-				A96F4EEC1E7D86D8000509B3 /* gravity_json.h */,
-				A96F4EED1E7D86D8000509B3 /* gravity_utils.c */,
-				A96F4EEE1E7D86D8000509B3 /* gravity_utils.h */,
-			);
-			name = utils;
-			path = ../../src/utils;
-			sourceTree = "<group>";
-		};
-		A96F4F031E7D8706000509B3 /* Sources */ = {
-			isa = PBXGroup;
-			children = (
-				A96F4F041E7D8706000509B3 /* BTFCodeEditor.h */,
-				A96F4F051E7D8706000509B3 /* BTFCodeEditor.m */,
-				A96F4F061E7D8706000509B3 /* BTFDelegate.h */,
-				A96F4F071E7D8706000509B3 /* BTFPopover.h */,
-				A96F4F081E7D8706000509B3 /* BTFPopover.m */,
-				A96F4F091E7D8706000509B3 /* BTFPopoverFrame.h */,
-				A96F4F0A1E7D8706000509B3 /* BTFPopoverFrame.m */,
-				A96F4F0B1E7D8706000509B3 /* BTFPopoverWindow.h */,
-				A96F4F0C1E7D8706000509B3 /* BTFPopoverWindow.m */,
-				A96F4F0D1E7D8706000509B3 /* BTFRulerView.h */,
-				A96F4F0E1E7D8706000509B3 /* BTFRulerView.m */,
-				A96F4F0F1E7D8706000509B3 /* BTFTextView.h */,
-				A96F4F101E7D8706000509B3 /* BTFTextView.m */,
-				A96F4F111E7D8706000509B3 /* BTFThemeKeys.h */,
-			);
-			name = Sources;
-			path = Butterfly/Sources;
-			sourceTree = "<group>";
-		};
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
-		A96F4EA51E7D8638000509B3 /* Butterfly */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = A96F4EB71E7D8638000509B3 /* Build configuration list for PBXNativeTarget "Butterfly" */;
-			buildPhases = (
-				A96F4EA21E7D8638000509B3 /* Sources */,
-				A96F4EA31E7D8638000509B3 /* Frameworks */,
-				A96F4EA41E7D8638000509B3 /* Resources */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-			);
-			name = Butterfly;
-			productName = Butterfly;
-			productReference = A96F4EA61E7D8638000509B3 /* Butterfly.app */;
-			productType = "com.apple.product-type.application";
-		};
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
-		A96F4E9E1E7D8638000509B3 /* Project object */ = {
-			isa = PBXProject;
-			attributes = {
-				LastUpgradeCheck = 0820;
-				ORGANIZATIONNAME = Creolabs;
-				TargetAttributes = {
-					A96F4EA51E7D8638000509B3 = {
-						CreatedOnToolsVersion = 8.2.1;
-						ProvisioningStyle = Automatic;
-					};
-				};
-			};
-			buildConfigurationList = A96F4EA11E7D8638000509B3 /* Build configuration list for PBXProject "Butterfly" */;
-			compatibilityVersion = "Xcode 3.2";
-			developmentRegion = English;
-			hasScannedForEncodings = 0;
-			knownRegions = (
-				en,
-				Base,
-			);
-			mainGroup = A96F4E9D1E7D8638000509B3;
-			productRefGroup = A96F4EA71E7D8638000509B3 /* Products */;
-			projectDirPath = "";
-			projectRoot = "";
-			targets = (
-				A96F4EA51E7D8638000509B3 /* Butterfly */,
-			);
-		};
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
-		A96F4EA41E7D8638000509B3 /* Resources */ = {
-			isa = PBXResourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				A96F4EBB1E7D8696000509B3 /* Themes in Resources */,
-				A96F4EB01E7D8638000509B3 /* Assets.xcassets in Resources */,
-				A96F4EB31E7D8638000509B3 /* MainMenu.xib in Resources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
-		A96F4EA21E7D8638000509B3 /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				A96F4EFF1E7D86D8000509B3 /* gravity_value.c in Sources */,
-				A96F4EF01E7D86D8000509B3 /* gravity_codegen.c in Sources */,
-				A96F4EFE1E7D86D8000509B3 /* gravity_memory.c in Sources */,
-				A96F4EFB1E7D86D8000509B3 /* gravity_core.c in Sources */,
-				A96F4F171E7D8706000509B3 /* BTFTextView.m in Sources */,
-				A96F4EEF1E7D86D8000509B3 /* gravity_ast.c in Sources */,
-				A96F4EF21E7D86D8000509B3 /* gravity_ircode.c in Sources */,
-				A96F4F131E7D8706000509B3 /* BTFPopover.m in Sources */,
-				A96F4EF61E7D86D8000509B3 /* gravity_semacheck1.c in Sources */,
-				A96F4EFC1E7D86D8000509B3 /* gravity_vm.c in Sources */,
-				A96F4F001E7D86D8000509B3 /* gravity_debug.c in Sources */,
-				A96F4EAE1E7D8638000509B3 /* main.m in Sources */,
-				A96F4F161E7D8706000509B3 /* BTFRulerView.m in Sources */,
-				A96F4F021E7D86D8000509B3 /* gravity_utils.c in Sources */,
-				A96F4F121E7D8706000509B3 /* BTFCodeEditor.m in Sources */,
-				A96F4F011E7D86D8000509B3 /* gravity_json.c in Sources */,
-				A96F4EF41E7D86D8000509B3 /* gravity_optimizer.c in Sources */,
-				A96F4EF31E7D86D8000509B3 /* gravity_lexer.c in Sources */,
-				A96F4EF91E7D86D8000509B3 /* gravity_token.c in Sources */,
-				A96F4EFD1E7D86D8000509B3 /* gravity_hash.c in Sources */,
-				A96F4EF71E7D86D8000509B3 /* gravity_semacheck2.c in Sources */,
-				A96F4EFA1E7D86D8000509B3 /* gravity_visitor.c in Sources */,
-				A96F4F151E7D8706000509B3 /* BTFPopoverWindow.m in Sources */,
-				A96F4EAB1E7D8638000509B3 /* AppDelegate.m in Sources */,
-				A96F4EF81E7D86D8000509B3 /* gravity_symboltable.c in Sources */,
-				A96F4EF51E7D86D8000509B3 /* gravity_parser.c in Sources */,
-				A96F4EF11E7D86D8000509B3 /* gravity_compiler.c in Sources */,
-				A96F4F141E7D8706000509B3 /* BTFPopoverFrame.m in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXVariantGroup section */
-		A96F4EB11E7D8638000509B3 /* MainMenu.xib */ = {
-			isa = PBXVariantGroup;
-			children = (
-				A96F4EB21E7D8638000509B3 /* Base */,
-			);
-			name = MainMenu.xib;
-			sourceTree = "<group>";
-		};
-/* End PBXVariantGroup section */
-
-/* Begin XCBuildConfiguration section */
-		A96F4EB51E7D8638000509B3 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				CLANG_ANALYZER_NONNULL = YES;
-				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
-				CLANG_CXX_LIBRARY = "libc++";
-				CLANG_ENABLE_MODULES = YES;
-				CLANG_ENABLE_OBJC_ARC = YES;
-				CLANG_WARN_BOOL_CONVERSION = YES;
-				CLANG_WARN_CONSTANT_CONVERSION = YES;
-				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
-				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
-				CLANG_WARN_EMPTY_BODY = YES;
-				CLANG_WARN_ENUM_CONVERSION = YES;
-				CLANG_WARN_INFINITE_RECURSION = YES;
-				CLANG_WARN_INT_CONVERSION = YES;
-				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
-				CLANG_WARN_SUSPICIOUS_MOVE = YES;
-				CLANG_WARN_UNREACHABLE_CODE = YES;
-				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
-				CODE_SIGN_IDENTITY = "-";
-				COPY_PHASE_STRIP = NO;
-				DEBUG_INFORMATION_FORMAT = dwarf;
-				ENABLE_STRICT_OBJC_MSGSEND = YES;
-				ENABLE_TESTABILITY = YES;
-				GCC_C_LANGUAGE_STANDARD = gnu99;
-				GCC_DYNAMIC_NO_PIC = NO;
-				GCC_NO_COMMON_BLOCKS = YES;
-				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"DEBUG=1",
-					"$(inherited)",
-				);
-				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
-				GCC_WARN_UNDECLARED_SELECTOR = YES;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
-				GCC_WARN_UNUSED_FUNCTION = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				MACOSX_DEPLOYMENT_TARGET = 10.12;
-				MTL_ENABLE_DEBUG_INFO = YES;
-				ONLY_ACTIVE_ARCH = YES;
-				SDKROOT = macosx;
-			};
-			name = Debug;
-		};
-		A96F4EB61E7D8638000509B3 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ALWAYS_SEARCH_USER_PATHS = NO;
-				CLANG_ANALYZER_NONNULL = YES;
-				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
-				CLANG_CXX_LIBRARY = "libc++";
-				CLANG_ENABLE_MODULES = YES;
-				CLANG_ENABLE_OBJC_ARC = YES;
-				CLANG_WARN_BOOL_CONVERSION = YES;
-				CLANG_WARN_CONSTANT_CONVERSION = YES;
-				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
-				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
-				CLANG_WARN_EMPTY_BODY = YES;
-				CLANG_WARN_ENUM_CONVERSION = YES;
-				CLANG_WARN_INFINITE_RECURSION = YES;
-				CLANG_WARN_INT_CONVERSION = YES;
-				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
-				CLANG_WARN_SUSPICIOUS_MOVE = YES;
-				CLANG_WARN_UNREACHABLE_CODE = YES;
-				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
-				CODE_SIGN_IDENTITY = "-";
-				COPY_PHASE_STRIP = NO;
-				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
-				ENABLE_NS_ASSERTIONS = NO;
-				ENABLE_STRICT_OBJC_MSGSEND = YES;
-				GCC_C_LANGUAGE_STANDARD = gnu99;
-				GCC_NO_COMMON_BLOCKS = YES;
-				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
-				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
-				GCC_WARN_UNDECLARED_SELECTOR = YES;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
-				GCC_WARN_UNUSED_FUNCTION = YES;
-				GCC_WARN_UNUSED_VARIABLE = YES;
-				MACOSX_DEPLOYMENT_TARGET = 10.12;
-				MTL_ENABLE_DEBUG_INFO = NO;
-				SDKROOT = macosx;
-			};
-			name = Release;
-		};
-		A96F4EB81E7D8638000509B3 /* Debug */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
-				COMBINE_HIDPI_IMAGES = YES;
-				INFOPLIST_FILE = Butterfly/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
-				PRODUCT_BUNDLE_IDENTIFIER = com.creolabs.Butterfly;
-				PRODUCT_NAME = "$(TARGET_NAME)";
-			};
-			name = Debug;
-		};
-		A96F4EB91E7D8638000509B3 /* Release */ = {
-			isa = XCBuildConfiguration;
-			buildSettings = {
-				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
-				COMBINE_HIDPI_IMAGES = YES;
-				INFOPLIST_FILE = Butterfly/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
-				PRODUCT_BUNDLE_IDENTIFIER = com.creolabs.Butterfly;
-				PRODUCT_NAME = "$(TARGET_NAME)";
-			};
-			name = Release;
-		};
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-		A96F4EA11E7D8638000509B3 /* Build configuration list for PBXProject "Butterfly" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				A96F4EB51E7D8638000509B3 /* Debug */,
-				A96F4EB61E7D8638000509B3 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
-		A96F4EB71E7D8638000509B3 /* Build configuration list for PBXNativeTarget "Butterfly" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				A96F4EB81E7D8638000509B3 /* Debug */,
-				A96F4EB91E7D8638000509B3 /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-		};
-/* End XCConfigurationList section */
-	};
-	rootObject = A96F4E9E1E7D8638000509B3 /* Project object */;
-}

+ 0 - 15
projects/Butterfly/Butterfly/AppDelegate.h

@@ -1,15 +0,0 @@
-//
-//  AppDelegate.h
-//  Butterfly
-//
-//  Created by Marco Bambini on 18/03/2017.
-//  Copyright © 2017 Creolabs. All rights reserved.
-//
-
-#import <Cocoa/Cocoa.h>
-
-@interface AppDelegate : NSObject <NSApplicationDelegate>
-
-
-@end
-

+ 0 - 103
projects/Butterfly/Butterfly/AppDelegate.m

@@ -1,103 +0,0 @@
-//
-//  AppDelegate.m
-//  Butterfly
-//
-//  Created by Marco Bambini on 18/03/2017.
-//  Copyright © 2017 Creolabs. All rights reserved.
-//
-
-#import "AppDelegate.h"
-#import "BTFThemeKeys.h"
-#import "BTFCodeEditor.h"
-#import "gravity_token.h"
-
-@interface AppDelegate () {
-	BTFCodeEditor                  *codeEditor;
-}
-
-@property (weak) IBOutlet NSWindow *window;
-@property (weak) IBOutlet NSView   *codeEditorView;
-@end
-
-@implementation AppDelegate
-
-// MARK: Utils functions
-
-static NSColor *colorFromHexadecimalValue(NSString *hex) {
-	if ([hex hasPrefix:@"#"]) {
-		hex = [hex substringWithRange:NSMakeRange(1, [hex length] - 1)];
-	}
-	
-	unsigned int colorCode = 0;
-	
-	// if string has only 6 characters append FF, opaque color
-	if (hex.length == 6)
-		hex = [NSString stringWithFormat:@"%@FF", hex];
-	
-	if (hex) {
-		NSScanner *scanner = [NSScanner scannerWithString:hex];
-		if (![scanner scanHexInt:&colorCode] || ! [scanner isAtEnd]) return nil;
-	}
-	
-	return [NSColor colorWithCalibratedRed:((colorCode>>24)&0xFF)/255.0 green:((colorCode>>16)&0xFF)/255.0 blue:((colorCode>>8)&0xFF)/255.0 alpha:((colorCode)&0xFF)/255.0];
-}
-
-static NSDictionary *deserializeTheme(NSDictionary *theme) {
-	NSMutableDictionary	*d = [[NSMutableDictionary alloc] initWithCapacity:theme.count];
-	
-	// ADJUST FONT
-	CGFloat		fontSize = 13;
-	NSString	*fontName = @"Menlo-Regular";
-	NSString	*boldFontName = @"Menlo-Bold";
-	NSFont		*fontRegular = nil;
-	NSFont		*fontBold = nil;
-	
-	if (theme[BTFKEY_FONT_SIZE]) fontSize = ((NSNumber*)theme[BTFKEY_FONT_SIZE]).floatValue;
-	if (theme[BTFKEY_FONT]) fontName = theme[BTFKEY_FONT];
-	if (theme[BTFKEY_BOLD_FONT]) boldFontName = theme[BTFKEY_BOLD_FONT];
-	fontRegular = [NSFont fontWithName:fontName size:fontSize];
-	fontBold = [NSFont fontWithName:boldFontName size:fontSize];
-	d[BTFKEY_FONT] = fontRegular;
-	d[BTFKEY_BOLD_FONT] = fontBold;
-	
-	// ADJUST all other values
-	for (NSString *key in theme.allKeys) {
-		if ([key hasSuffix:@"COLOR"]) d[key] = colorFromHexadecimalValue(theme[key]);
-		else if ([key hasSuffix:@"IMAGE"]) d[key] = [NSImage imageNamed:(theme[key])];
-		else if ([key containsString:@"FONT"]) continue;
-		else d[key] = theme[key];
-	}
-	
-	return d;
-}
-
-- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
-	codeEditor = [[BTFCodeEditor alloc] initWithFrame:_codeEditorView.frame inView:_window];
-	
-	// apply theme (available themes are: Gauss, Laplace, Fourier and Riemann)
-	NSURL *themeURL = [[NSBundle mainBundle] URLForResource:@"Gauss" withExtension:@"theme" subdirectory:@"Themes"];
-	NSData *data = [NSData dataWithContentsOfURL:themeURL];
-	NSDictionary *theme = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
-	// it is caller responsability to propertly deserize theme
-	[codeEditor applyTheme:deserializeTheme(theme)];
-	
-	// add reserved keywords to autocompletion engine
-	// set reserved keywords
-	uint32_t i, idx_end;
-	token_keywords_indexes(&i, &idx_end);
-	for (; i<=idx_end; ++i) {
-		const char *keyword = token_name(i);
-		if (keyword) [codeEditor addAutocompleteEntity:[NSString stringWithUTF8String:keyword] type:0];
-	}
-	
-	// UTF-8 EXAMPLE
-	codeEditor.string = @" // UTF-8 4 bytes\nvar a = \" 😀 a b\";\n\n// UTF-8 3 bytes\nvar b = \" 肉 a b\";\n\n// UTF-8 2 bytes\nvar c = \" © a b\";\n\n// UTF-8 1 byte\nvar d = \" a a b\";";
-}
-
-
-- (void)applicationWillTerminate:(NSNotification *)aNotification {
-	// Insert code here to tear down your application
-}
-
-
-@end

+ 0 - 58
projects/Butterfly/Butterfly/Assets.xcassets/AppIcon.appiconset/Contents.json

@@ -1,58 +0,0 @@
-{
-  "images" : [
-    {
-      "idiom" : "mac",
-      "size" : "16x16",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "mac",
-      "size" : "16x16",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "mac",
-      "size" : "32x32",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "mac",
-      "size" : "32x32",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "mac",
-      "size" : "128x128",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "mac",
-      "size" : "128x128",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "mac",
-      "size" : "256x256",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "mac",
-      "size" : "256x256",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "mac",
-      "size" : "512x512",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "mac",
-      "size" : "512x512",
-      "scale" : "2x"
-    }
-  ],
-  "info" : {
-    "version" : 1,
-    "author" : "xcode"
-  }
-}

+ 0 - 703
projects/Butterfly/Butterfly/Base.lproj/MainMenu.xib

@@ -1,703 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
-    <dependencies>
-        <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
-            <connections>
-                <outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
-            </connections>
-        </customObject>
-        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
-        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
-        <customObject id="Voe-Tx-rLC" customClass="AppDelegate">
-            <connections>
-                <outlet property="codeEditorView" destination="SvY-0R-ahY" id="YV8-yM-HWN"/>
-                <outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
-            </connections>
-        </customObject>
-        <customObject id="YLy-65-1bz" customClass="NSFontManager"/>
-        <menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
-            <items>
-                <menuItem title="Butterfly" id="1Xt-HY-uBw">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Butterfly" systemMenu="apple" id="uQy-DD-JDr">
-                        <items>
-                            <menuItem title="About Butterfly" id="5kV-Vb-QxS">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
-                            <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
-                            <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
-                            <menuItem title="Services" id="NMo-om-nkz">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
-                            <menuItem title="Hide Butterfly" keyEquivalent="h" id="Olw-nP-bQN">
-                                <connections>
-                                    <action selector="hide:" target="-1" id="PnN-Uc-m68"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
-                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                <connections>
-                                    <action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Show All" id="Kd2-mp-pUS">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
-                            <menuItem title="Quit Butterfly" keyEquivalent="q" id="4sb-4s-VLi">
-                                <connections>
-                                    <action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="File" id="dMs-cI-mzQ">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="File" id="bib-Uj-vzu">
-                        <items>
-                            <menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
-                                <connections>
-                                    <action selector="newDocument:" target="-1" id="4Si-XN-c54"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
-                                <connections>
-                                    <action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Open Recent" id="tXI-mr-wws">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
-                                    <items>
-                                        <menuItem title="Clear Menu" id="vNY-rz-j42">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="clearRecentDocuments:" target="-1" id="Daa-9d-B3U"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
-                            <menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
-                                <connections>
-                                    <action selector="performClose:" target="-1" id="HmO-Ls-i7Q"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
-                                <connections>
-                                    <action selector="saveDocument:" target="-1" id="teZ-XB-qJY"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
-                                <connections>
-                                    <action selector="saveDocumentAs:" target="-1" id="mDf-zr-I0C"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Revert to Saved" keyEquivalent="r" id="KaW-ft-85H">
-                                <connections>
-                                    <action selector="revertDocumentToSaved:" target="-1" id="iJ3-Pv-kwq"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
-                            <menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
-                                <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
-                                <connections>
-                                    <action selector="runPageLayout:" target="-1" id="Din-rz-gC5"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
-                                <connections>
-                                    <action selector="print:" target="-1" id="qaZ-4w-aoO"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="Edit" id="5QF-Oa-p0T">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Edit" id="W48-6f-4Dl">
-                        <items>
-                            <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
-                                <connections>
-                                    <action selector="undo:" target="-1" id="M6e-cu-g7V"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
-                                <connections>
-                                    <action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
-                            <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
-                                <connections>
-                                    <action selector="cut:" target="-1" id="YJe-68-I9s"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
-                                <connections>
-                                    <action selector="copy:" target="-1" id="G1f-GL-Joy"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
-                                <connections>
-                                    <action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
-                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                <connections>
-                                    <action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Delete" id="pa3-QI-u2k">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
-                                <connections>
-                                    <action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
-                            <menuItem title="Find" id="4EN-yA-p0u">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Find" id="1b7-l0-nxx">
-                                    <items>
-                                        <menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
-                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
-                                            <connections>
-                                                <action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
-                                            <connections>
-                                                <action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
-                                    <items>
-                                        <menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
-                                            <connections>
-                                                <action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
-                                            <connections>
-                                                <action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
-                                        <menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Substitutions" id="9ic-FL-obx">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
-                                    <items>
-                                        <menuItem title="Show Substitutions" id="z6F-FW-3nz">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
-                                        <menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Smart Quotes" id="hQb-2v-fYv">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Smart Dashes" id="rgM-f4-ycn">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Smart Links" id="cwL-P1-jid">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Data Detectors" id="tRr-pd-1PS">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Text Replacement" id="HFQ-gK-NFA">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Transformations" id="2oI-Rn-ZJC">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Transformations" id="c8a-y6-VQd">
-                                    <items>
-                                        <menuItem title="Make Upper Case" id="vmV-6d-7jI">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Make Lower Case" id="d9M-CD-aMd">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Capitalize" id="UEZ-Bs-lqG">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Speech" id="xrE-MZ-jX0">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Speech" id="3rS-ZA-NoH">
-                                    <items>
-                                        <menuItem title="Start Speaking" id="Ynk-f8-cLZ">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Stop Speaking" id="Oyz-dy-DGm">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="Format" id="jxT-CU-nIS">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Format" id="GEO-Iw-cKr">
-                        <items>
-                            <menuItem title="Font" id="Gi5-1S-RQB">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
-                                    <items>
-                                        <menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
-                                            <connections>
-                                                <action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
-                                            <connections>
-                                                <action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
-                                            <connections>
-                                                <action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
-                                            <connections>
-                                                <action selector="underline:" target="-1" id="FYS-2b-JAY"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
-                                        <menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
-                                            <connections>
-                                                <action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
-                                            <connections>
-                                                <action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
-                                        <menuItem title="Kern" id="jBQ-r6-VK2">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <menu key="submenu" title="Kern" id="tlD-Oa-oAM">
-                                                <items>
-                                                    <menuItem title="Use Default" id="GUa-eO-cwY">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="useStandardKerning:" target="-1" id="6dk-9l-Ckg"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Use None" id="cDB-IK-hbR">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="turnOffKerning:" target="-1" id="U8a-gz-Maa"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Tighten" id="46P-cB-AYj">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="tightenKerning:" target="-1" id="hr7-Nz-8ro"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Loosen" id="ogc-rX-tC1">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="loosenKerning:" target="-1" id="8i4-f9-FKE"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                </items>
-                                            </menu>
-                                        </menuItem>
-                                        <menuItem title="Ligatures" id="o6e-r0-MWq">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
-                                                <items>
-                                                    <menuItem title="Use Default" id="agt-UL-0e3">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="useStandardLigatures:" target="-1" id="7uR-wd-Dx6"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Use None" id="J7y-lM-qPV">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="turnOffLigatures:" target="-1" id="iX2-gA-Ilz"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Use All" id="xQD-1f-W4t">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="useAllLigatures:" target="-1" id="KcB-kA-TuK"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                </items>
-                                            </menu>
-                                        </menuItem>
-                                        <menuItem title="Baseline" id="OaQ-X3-Vso">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <menu key="submenu" title="Baseline" id="ijk-EB-dga">
-                                                <items>
-                                                    <menuItem title="Use Default" id="3Om-Ey-2VK">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="unscript:" target="-1" id="0vZ-95-Ywn"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Superscript" id="Rqc-34-cIF">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="superscript:" target="-1" id="3qV-fo-wpU"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Subscript" id="I0S-gh-46l">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="subscript:" target="-1" id="Q6W-4W-IGz"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Raise" id="2h7-ER-AoG">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="raiseBaseline:" target="-1" id="4sk-31-7Q9"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem title="Lower" id="1tx-W0-xDw">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="lowerBaseline:" target="-1" id="OF1-bc-KW4"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                </items>
-                                            </menu>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
-                                        <menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
-                                            <connections>
-                                                <action selector="orderFrontColorPanel:" target="-1" id="mSX-Xz-DV3"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
-                                        <menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
-                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="copyFont:" target="-1" id="GJO-xA-L4q"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
-                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="pasteFont:" target="-1" id="JfD-CL-leO"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                            <menuItem title="Text" id="Fal-I4-PZk">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <menu key="submenu" title="Text" id="d9c-me-L2H">
-                                    <items>
-                                        <menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
-                                            <connections>
-                                                <action selector="alignLeft:" target="-1" id="zUv-R1-uAa"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
-                                            <connections>
-                                                <action selector="alignCenter:" target="-1" id="spX-mk-kcS"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Justify" id="J5U-5w-g23">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="alignJustified:" target="-1" id="ljL-7U-jND"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
-                                            <connections>
-                                                <action selector="alignRight:" target="-1" id="r48-bG-YeY"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
-                                        <menuItem title="Writing Direction" id="H1b-Si-o9J">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
-                                                <items>
-                                                    <menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                    </menuItem>
-                                                    <menuItem id="YGs-j5-SAR">
-                                                        <string key="title">	Default</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeBaseWritingDirectionNatural:" target="-1" id="qtV-5e-UBP"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem id="Lbh-J2-qVU">
-                                                        <string key="title">	Left to Right</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="S0X-9S-QSf"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem id="jFq-tB-4Kx">
-                                                        <string key="title">	Right to Left</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="5fk-qB-AqJ"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
-                                                    <menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                    </menuItem>
-                                                    <menuItem id="Nop-cj-93Q">
-                                                        <string key="title">	Default</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeTextWritingDirectionNatural:" target="-1" id="lPI-Se-ZHp"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem id="BgM-ve-c93">
-                                                        <string key="title">	Left to Right</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="caW-Bv-w94"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                    <menuItem id="RB4-Sm-HuC">
-                                                        <string key="title">	Right to Left</string>
-                                                        <modifierMask key="keyEquivalentModifierMask"/>
-                                                        <connections>
-                                                            <action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="EXD-6r-ZUu"/>
-                                                        </connections>
-                                                    </menuItem>
-                                                </items>
-                                            </menu>
-                                        </menuItem>
-                                        <menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
-                                        <menuItem title="Show Ruler" id="vLm-3I-IUL">
-                                            <modifierMask key="keyEquivalentModifierMask"/>
-                                            <connections>
-                                                <action selector="toggleRuler:" target="-1" id="FOx-HJ-KwY"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
-                                            <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="copyRuler:" target="-1" id="71i-fW-3W2"/>
-                                            </connections>
-                                        </menuItem>
-                                        <menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
-                                            <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
-                                            <connections>
-                                                <action selector="pasteRuler:" target="-1" id="cSh-wd-qM2"/>
-                                            </connections>
-                                        </menuItem>
-                                    </items>
-                                </menu>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="View" id="H8h-7b-M4v">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="View" id="HyV-fh-RgO">
-                        <items>
-                            <menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
-                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
-                                <connections>
-                                    <action selector="toggleToolbarShown:" target="-1" id="BXY-wc-z0C"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="runToolbarCustomizationPalette:" target="-1" id="pQI-g3-MTW"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="hB3-LF-h0Y"/>
-                            <menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE">
-                                <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
-                                <connections>
-                                    <action selector="toggleSourceList:" target="-1" id="iwa-gc-5KM"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
-                                <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
-                                <connections>
-                                    <action selector="toggleFullScreen:" target="-1" id="dU3-MA-1Rq"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="Window" id="aUF-d1-5bR">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
-                        <items>
-                            <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
-                                <connections>
-                                    <action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem title="Zoom" id="R4o-n2-Eq4">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
-                                </connections>
-                            </menuItem>
-                            <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
-                            <menuItem title="Bring All to Front" id="LE2-aR-0XJ">
-                                <modifierMask key="keyEquivalentModifierMask"/>
-                                <connections>
-                                    <action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-                <menuItem title="Help" id="wpr-3q-Mcd">
-                    <modifierMask key="keyEquivalentModifierMask"/>
-                    <menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
-                        <items>
-                            <menuItem title="Butterfly Help" keyEquivalent="?" id="FKE-Sm-Kum">
-                                <connections>
-                                    <action selector="showHelp:" target="-1" id="y7X-2Q-9no"/>
-                                </connections>
-                            </menuItem>
-                        </items>
-                    </menu>
-                </menuItem>
-            </items>
-        </menu>
-        <window title="Butterfly" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
-            <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
-            <windowPositionMask key="initialPositionMask" topStrut="YES" bottomStrut="YES"/>
-            <rect key="contentRect" x="476" y="359" width="580" height="420"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
-            <value key="minSize" type="size" width="400" height="320"/>
-            <view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
-                <rect key="frame" x="0.0" y="0.0" width="580" height="420"/>
-                <autoresizingMask key="autoresizingMask"/>
-                <subviews>
-                    <customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SvY-0R-ahY">
-                        <rect key="frame" x="0.0" y="0.0" width="580" height="420"/>
-                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                    </customView>
-                </subviews>
-            </view>
-            <point key="canvasLocation" x="296.5" y="-79.5"/>
-        </window>
-    </objects>
-</document>

+ 0 - 32
projects/Butterfly/Butterfly/Info.plist

@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>CFBundleDevelopmentRegion</key>
-	<string>en</string>
-	<key>CFBundleExecutable</key>
-	<string>$(EXECUTABLE_NAME)</string>
-	<key>CFBundleIconFile</key>
-	<string></string>
-	<key>CFBundleIdentifier</key>
-	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
-	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.0</string>
-	<key>CFBundleName</key>
-	<string>$(PRODUCT_NAME)</string>
-	<key>CFBundlePackageType</key>
-	<string>APPL</string>
-	<key>CFBundleShortVersionString</key>
-	<string>1.0</string>
-	<key>CFBundleVersion</key>
-	<string>1</string>
-	<key>LSMinimumSystemVersion</key>
-	<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
-	<key>NSHumanReadableCopyright</key>
-	<string>Copyright © 2017 Creolabs. All rights reserved.</string>
-	<key>NSMainNibFile</key>
-	<string>MainMenu</string>
-	<key>NSPrincipalClass</key>
-	<string>NSApplication</string>
-</dict>
-</plist>

+ 0 - 33
projects/Butterfly/Butterfly/Sources/BTFCodeEditor.h

@@ -1,33 +0,0 @@
-//
-//  BTFCodeEditor.h
-//  Butterfly
-//
-//  Created by Marco Bambini on 15/07/15.
-//  Copyright (c) 2015 Marco Bambini. All rights reserved.
-//
-
-#import <Cocoa/Cocoa.h>
-#import "BTFDelegate.h"
-
-@interface BTFCodeEditor : NSObject
-
-@property (nonatomic, weak) id<BTFCodeEditorDelegate>	delegate;
-@property (nonatomic)		NSString					*string;
-@property (nonatomic)		BOOL						editable;
-@property (readonly)		CGFloat						ruleThickness;
-@property (nonatomic)		BOOL						changed;
-
-- (instancetype) initWithFrame:(NSRect)frame inView:(id)aView;
-- (void) applyTheme:(NSDictionary *)theme;
-- (void) setFocus;
-
-- (void) resetAutocompleteEntities;
-- (void) addAutocompleteEntity:(NSString *)key type:(int)type;
-- (void) removeAutocompleteEntity:(NSString *)key;
-
-- (NSUInteger) mousePointToIndex:(NSPoint)p;
-- (void) tempString:(NSString *)s insertAtIndex:(NSUInteger)idx;
-- (void) tempStringFinalize;
-- (void) clearUndoManager:(NSUndoManager *)undoManager;
-
-@end

+ 0 - 286
projects/Butterfly/Butterfly/Sources/BTFCodeEditor.m

@@ -1,286 +0,0 @@
-//
-//  BTFCodeEditor.m
-//  Butterfly
-//
-//  Created by Marco Bambini on 15/07/15.
-//  Copyright (c) 2015 Marco Bambini. All rights reserved.
-//
-
-#import "BTFCodeEditor.h"
-#import "BTFRulerView.h"
-#import "BTFThemeKeys.h"
-#import "BTFTextView.h"
-
-#define BTF_DEFAULT_RIGHT_PADDING		10.0f
-
-@interface BTFCodeEditor() <NSTextDelegate, NSTextViewDelegate, BTFCodeEditorDelegate> {
-    NSScrollView		*scrollView;
-    BTFRulerView		*rulerView;
-    BTFTextView			*textView;
-    __weak NSWindow		*mainWindow;
-	BOOL				collectChanges;
-	
-	// autocomplete
-	NSMutableArray		*keys;
-	
-	// temp
-	NSUInteger			tempLength;
-	NSUInteger			tempIndex;
-}
-@end
-
-@implementation BTFCodeEditor
-@synthesize changed;
-
-- (instancetype) initWithFrame:(NSRect)frame inView:(id)aView; {
-    self = [super init];
-    if (self) {
-		collectChanges = NO;
-		
-        // setup scrollview
-        scrollView = [[NSScrollView alloc] initWithFrame:frame];
-        NSSize contentSize = [scrollView contentSize];
-        [scrollView setBorderType:NSNoBorder];
-        [scrollView setHasVerticalScroller:YES];
-        [scrollView setHasHorizontalScroller:NO];
-        [scrollView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
-		
-        // setup textview
-        textView = [[BTFTextView alloc] initWithFrame:NSMakeRect(0, 0, contentSize.width, contentSize.height)];
-		
-		// setup rulerview
-		rulerView = [[BTFRulerView alloc] initWithBTFTextView:textView];
-		scrollView.verticalRulerView = rulerView;
-		scrollView.hasVerticalRuler = true;
-		scrollView.rulersVisible = true;
-		
-		// set textview settings
-        [textView setMinSize:NSMakeSize(0.0, contentSize.height)];
-        [textView setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
-        [textView setVerticallyResizable:YES];
-        [textView setHorizontallyResizable:NO];
-        [textView setAutoresizingMask:NSViewWidthSizable];
-        [[textView textContainer] setContainerSize:NSMakeSize(contentSize.width-(rulerView.ruleThickness + BTF_DEFAULT_RIGHT_PADDING), FLT_MAX)];
-        [[textView textContainer] setWidthTracksTextView:YES];
-		textView.BTFDelegate = self;
-		textView.rulerView = rulerView;
-		
-        // connect scrollView to textView
-        [scrollView setDocumentView:textView];
-        
-        // setup window connections (if any)
-		if ([aView isKindOfClass:[NSView class]]) {
-			[(NSView *)aView addSubview:scrollView];
-		} else {
-			NSWindow *aWindow = (NSWindow *)aView;
-			mainWindow = aWindow;
-			[aWindow setContentView:scrollView];
-			[aWindow makeKeyAndOrderFront:nil];
-			[aWindow makeFirstResponder:textView];
-		}
-		
-		// setup autocompletion
-		keys = [NSMutableArray array];
-		
-		// setup observers
-		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(frameDidChange:)
-													 name:NSViewFrameDidChangeNotification object:textView];
-		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange:)
-													 name:NSTextDidChangeNotification object:textView];
-    }
-    return self;
-}
-
-- (void)dealloc {
-	[[NSNotificationCenter defaultCenter] removeObserver:self];
-}
-
-- (void)setString:(NSString *)aString {
-	collectChanges = NO;
-	textView.string = (aString) ? aString : @"";
-	[rulerView setNeedsDisplay:YES];
-	collectChanges = YES;
-}
-
-- (NSString *)string {
-	return textView.string;
-}
-
-- (void)setEditable:(BOOL)editable {
-	[textView setEditable:editable];
-}
-
-- (void)setFocus {
-	[textView.window makeFirstResponder:textView];
-}
-
-- (BOOL)editable {
-	return textView.editable;
-}
-
-- (void) clearUndoManager:(NSUndoManager *)undoManager {
-	[undoManager removeAllActionsWithTarget:textView.textStorage];
-}
-
-#pragma mark - Autocompletion -
-
-- (void) resetAutocompleteEntities {
-	[keys removeAllObjects];
-}
-
-- (void) addAutocompleteEntity:(NSString *)key type:(int)type {
-	[keys addObject:key];
-}
-
-- (void) removeAutocompleteEntity:(NSString *)key {
-	[keys removeObject:key];
-}
-
-#pragma mark - Temp -
-
-- (void) tempString:(NSString *)s insertAtIndex:(NSUInteger)idx {
-	[self tempStringRemove];
-	if (!s) {[textView setNeedsDisplay:YES]; return;}
-	
-	// insert temp string into textview
-	[textView setSelectedRange:NSMakeRange(idx,0)];
-	[textView insertText:s];
-	
-	// set temp string coordinates
-	tempIndex = idx;
-	tempLength = s.length;
-	[textView setNeedsDisplay:YES];
-}
-
-- (void) tempStringFinalize {
-	tempLength = 0;
-	[textView setNeedsDisplay:YES];
-}
-
-- (void) tempStringRemove {
-	if (tempLength == 0) return;
-	NSRange range = NSMakeRange(tempIndex, tempLength);
-	NSString *string = [textView textStorage].string;
-	
-	// sanity check range before apply the change
-	if (range.location != NSNotFound && range.location + range.length <= string.length) {
-		[[textView textStorage] deleteCharactersInRange:range];
-	}
-	tempLength = 0;
-}
-
-- (NSUInteger) mousePointToIndex:(NSPoint)p {
-	// p is in screen coordinates
-	NSRect rect = [textView.window convertRectFromScreen:NSMakeRect(p.x, p.y, 0, 0)];
-	NSPoint point = [textView convertPoint:rect.origin fromView:nil];
-	
-	// sanity check
-	if ((point.x < 0.0f) || (point.y < 0.0) ||
-		(floor(point.x) == 0) || (floor(point.y) == 0)) return NSUIntegerMax;
-	
-	// compute insertion index
-	NSUInteger insertionIndex = [textView characterIndexForInsertionAtPoint:point];
-	if (tempLength) {
-		if (insertionIndex >= tempIndex && insertionIndex <= tempIndex+tempLength) insertionIndex = tempIndex;
-		else if (insertionIndex > tempIndex+tempLength) insertionIndex -= tempLength;
-	}
-	
-	return insertionIndex;
-}
-
-#pragma mark - Observers -
-
-- (void) frameDidChange:(NSNotification *)notification {
-	NSSize contentSize = [scrollView contentSize];
-	[[textView textContainer] setContainerSize:NSMakeSize(contentSize.width-(rulerView.ruleThickness + BTF_DEFAULT_RIGHT_PADDING), FLT_MAX)];
-	[rulerView setNeedsDisplay:YES];
-}
-
-- (void) textDidChange:(NSNotification *)notification {
-	if (collectChanges) changed = YES;
-	[rulerView setNeedsDisplay:YES];
-}
-
-#pragma mark - Others -
-
-- (void) applyTheme:(NSDictionary *)theme {
-	// process keys that need to be always evaluated
-	if (theme[BTFKEY_RULER_BACKGROUND_COLOR])
-		rulerView.backgroundColor = theme[BTFKEY_RULER_BACKGROUND_COLOR];
-	if (theme[BTFKEY_RULER_TEXT_COLOR])
-		rulerView.textColor = theme[BTFKEY_RULER_TEXT_COLOR];
-	if (theme[BTFKEY_RULER_BORDER_COLOR])
-		rulerView.borderColor = theme[BTFKEY_RULER_BORDER_COLOR];
-	else
-		rulerView.borderColor = [NSColor clearColor];
-	if (theme[BTFKEY_RULER_BORDER_WIDTH])
-		rulerView.borderWidth = ((NSNumber*)theme[BTFKEY_RULER_BORDER_WIDTH]).floatValue;
-	else
-		rulerView.borderWidth = 0;
-	
-	[rulerView setNeedsDisplay:YES];
-	textView.theme = theme;
-}
-
-- (CGFloat)ruleThickness {
-	return rulerView.ruleThickness;
-}
-
-#pragma mark - BTFCodeEditorDelegate -
-
-- (NSArray *)textView:(NSTextView *)aTextView completions:(NSArray *)words forPartialWordRange:(NSRange)charRange
-			 location:(NSUInteger)location indexOfSelectedItem:(NSInteger *)index {
-	
-	NSMutableArray *matches = [NSMutableArray array];
-	NSString *text = [textView string];
-	NSString *target = [text substringWithRange:charRange];
-	
-//	NSLog(@"%@", target);
-//	NSLog(@"%@", words);
-	
-//	// do not autocomplete if in the middle of the string
-//	if (location < charRange.location + charRange.length) return matches;
-//	
-//	// autocomplete only if next character is not alpha
-//	if (text.length > charRange.location + charRange.length) {
-//		NSRange nextRange = NSMakeRange(charRange.location+1, 1);
-//		unichar nextChar = [[text substringWithRange:nextRange] characterAtIndex:0];
-//		bool isAlpha = ((nextChar >= 97 && nextChar <=122) || (nextChar >= 65 && nextChar <=90));
-//		NSLog(@"%d %d (%@)", isAlpha, nextChar, [text substringWithRange:nextRange]);
-//		if (!isAlpha) return matches;
-//	}
-	
-	if (words.count == 0) {
-		// scan keywords ONLY if there are no subtargets
-		for (NSString *string in keys) {
-			// do not autocomplete equal strings
-			if ([target isEqualToString:string]) continue;
-			
-			// search matches
-			if ([string rangeOfString:target options:NSAnchoredSearch | NSCaseInsensitiveSearch
-								range:NSMakeRange(0, [string length])].location != NSNotFound) {
-				[matches addObject:string];
-			}
-		}
-	}
-	[matches sortUsingSelector:@selector(compare:)];
-	return matches;
-}
-
-- (NSImage *)textView:(NSTextView *)textView imageForCompletion:(NSString *)word {
-//	NSImage *image = self.imageDict[word];
-//	if (image) {
-//		return image;
-//	}
-//	return self.imageDict[@"Unknown"];
-	return nil;
-}
-
-- (void)textDidEndEditing:(NSNotification *)notification {
-	if (!self.delegate) return;
-	if ([self.delegate respondsToSelector:@selector(textDidEndEditing:)]) {
-		[self.delegate textDidEndEditing:self];
-	}
-}
-
-@end

+ 0 - 16
projects/Butterfly/Butterfly/Sources/BTFDelegate.h

@@ -1,16 +0,0 @@
-//
-//  BTFDelegate.h
-//  Butterfly
-//
-//  Created by Marco Bambini on 11/09/15.
-//  Copyright (c) 2015 Marco Bambini. All rights reserved.
-//
-
-@protocol BTFCodeEditorDelegate <NSObject>
-@optional
-- (void) mouseMovedAtRange:(NSRange)range;
-- (void) textDidEndEditing:(id)sender;
-- (NSArray *)textView:(NSTextView *)textView completions:(NSArray *)words forPartialWordRange:(NSRange)charRange
-			 location:(NSUInteger)location indexOfSelectedItem:(NSInteger *)index;
-//- (NSImage *)textView:(NSTextView *)textView imageForCompletion:(NSString *)word;
-@end

+ 0 - 25
projects/Butterfly/Butterfly/Sources/BTFPopover.h

@@ -1,25 +0,0 @@
-//
-//  BTFPopover.h
-//  Butterfly
-//
-//  Created by Marco Bambini on 21/07/15.
-//  Copyright (c) 2015 Marco Bambini. All rights reserved.
-//
-
-//
-// Although the majority of the code was written by me, the inspiration and some code comes from:
-// NCRAutocompleteTextView by Daniel Weber on 9/28/14 - Copyright (c) 2014 Null Creature.
-// SFBPopover - Copyright (C) 2011, 2012, 2013, 2014, 2015 Stephen F. Booth <[email protected]>
-//
-
-#import <Cocoa/Cocoa.h>
-#import	"BTFPopoverWindow.h"
-
-@interface BTFPopover : NSResponder
-
-- (id) initWithContentView:(NSView *)contentView;
-- (void) displayPopoverInWindow:(NSWindow *)window atPoint:(NSPoint)point;
-- (void) closePopover:(id)sender;
-- (BTFPopoverWindow *) window;
-- (BOOL) isVisible;
-@end

+ 0 - 95
projects/Butterfly/Butterfly/Sources/BTFPopover.m

@@ -1,95 +0,0 @@
-//
-//  BTFPopover.m
-//  Butterfly
-//
-//  Created by Marco Bambini on 21/07/15.
-//  Copyright (c) 2015 Marco Bambini. All rights reserved.
-//
-
-#import "BTFPopover.h"
-#import "BTFPopoverFrame.h"
-
-@interface BTFPopover() {
-	NSViewController	*contentViewController;
-	BTFPopoverWindow	*popoverWindow;
-	BTFPopoverFrame		*popoverFrame;
-}
-@end
-
-@implementation BTFPopover
-
-- (id) init {
-	return [self initWithContentViewController:nil];
-}
-
-- (id) initWithContentView:(NSView *)contentView {
-	NSViewController *aContentViewController = [[NSViewController alloc] init];
-	
-	popoverFrame = [[BTFPopoverFrame alloc] initWithFrame:NSZeroRect];
-	[popoverFrame addSubview:contentView];
-	
-	[aContentViewController setView:popoverFrame];
-	return [self initWithContentViewController:aContentViewController];
-}
-
-- (id) initWithContentViewController:(NSViewController *)aContentViewController {
-	if((self = [super init])) {
-		contentViewController = aContentViewController;
-		
-		NSView *contentView = [contentViewController view];
-		popoverWindow = [[BTFPopoverWindow alloc] initWithContentRect:[contentView frame] backing:NSBackingStoreBuffered defer:YES];
-		[popoverWindow setContentView:contentView];
-		[popoverWindow setMinSize:[contentView frame].size];
-		
-		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidResignKey:)
-													 name:NSWindowDidResignKeyNotification object:popoverWindow];
-		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidResignActive:)
-													 name:NSApplicationDidResignActiveNotification object:nil];
-	}
-	return self;
-}
-
-- (void) displayPopoverInWindow:(NSWindow *)window atPoint:(NSPoint)point {
-	BOOL wasVisible = [popoverWindow isVisible];
-	[popoverWindow setFrameOrigin:point];
-	if (wasVisible) return;
-	
-	[window addChildWindow:popoverWindow ordered:NSWindowAbove];
-	[popoverWindow makeKeyAndOrderFront:nil];
-}
-
-- (void) dealloc {
-	[[NSNotificationCenter defaultCenter] removeObserver:self];
-}
-
-- (NSWindow *) window {
-	return popoverWindow;
-}
-
-- (BOOL) isVisible {
-	return [popoverWindow isVisible];
-}
-
-- (void) closePopover:(id)sender {
-	if(![popoverWindow isVisible]) return;
-	
-	NSWindow *parentWindow = [popoverWindow parentWindow];
-	[parentWindow removeChildWindow:popoverWindow];
-	[popoverWindow orderOut:sender];
-}
-@end
-
-@implementation BTFPopover (NSWindowDelegateMethods)
-
-- (void) windowDidResignKey:(NSNotification *)notification {
-	//NSLog(@"windowDidResignKey");
-	//if(self.closesWhenPopoverResignsKey)
-		//[self closePopover:notification];
-}
-
-- (void) applicationDidResignActive:(NSNotification *)notification{
-	//NSLog(@"applicationDidResignActive");
-		//[self closePopover:notification];
-}
-
-@end

+ 0 - 18
projects/Butterfly/Butterfly/Sources/BTFPopoverFrame.h

@@ -1,18 +0,0 @@
-//
-//  BTFPopoverFrame.h
-//  Butterfly
-//
-//  Created by Marco Bambini on 21/07/15.
-//  Copyright (c) 2015 Marco Bambini. All rights reserved.
-//
-
-#import <Cocoa/Cocoa.h>
-
-@interface BTFPopoverFrame : NSView
-
-@property (nonatomic, copy)	  NSColor *borderColor;
-@property (nonatomic, assign) CGFloat borderWidth;
-@property (nonatomic, assign) CGFloat cornerRadius;
-@property (nonatomic, copy)	  NSColor *backgroundColor;
-
-@end

+ 0 - 25
projects/Butterfly/Butterfly/Sources/BTFPopoverFrame.m

@@ -1,25 +0,0 @@
-//
-//  BTFPopoverFrame.m
-//  Butterfly
-//
-//  Created by Marco Bambini on 21/07/15.
-//  Copyright (c) 2015 Marco Bambini. All rights reserved.
-//
-
-#import "BTFPopoverFrame.h"
-
-@implementation BTFPopoverFrame
-
-- (id) initWithFrame:(NSRect)frame {
-	if ((self = [super initWithFrame:frame])) {
-		[self setWantsLayer:YES];
-		self.layer.backgroundColor = [NSColor colorWithCalibratedWhite:(CGFloat)1.0 alpha:(CGFloat)0.9].CGColor;
-		self.layer.borderColor = [NSColor darkGrayColor].CGColor;
-		self.layer.borderWidth = 0.5f;
-		self.layer.cornerRadius = 5;
-		self.layer.masksToBounds = YES;
-	}
-	return self;
-}
-
-@end

+ 0 - 13
projects/Butterfly/Butterfly/Sources/BTFPopoverWindow.h

@@ -1,13 +0,0 @@
-//
-//  BTFPopoverWindow.h
-//  Butterfly
-//
-//  Created by Marco Bambini on 21/07/15.
-//  Copyright (c) 2015 Marco Bambini. All rights reserved.
-//
-
-#import <Cocoa/Cocoa.h>
-
-@interface BTFPopoverWindow : NSWindow
-- (id) initWithContentRect:(NSRect)contentRect backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation;
-@end

+ 0 - 38
projects/Butterfly/Butterfly/Sources/BTFPopoverWindow.m

@@ -1,38 +0,0 @@
-//
-//  BTFPopoverWindow.m
-//  Butterfly
-//
-//  Created by Marco Bambini on 21/07/15.
-//  Copyright (c) 2015 Marco Bambini. All rights reserved.
-//
-
-#import "BTFPopoverWindow.h"
-
-@interface BTFPopoverWindow() {
-	NSView	*popoverContentView;
-}
-@end
-
-@implementation BTFPopoverWindow
-
-- (id) initWithContentRect:(NSRect)contentRect backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation {
-	if((self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:bufferingType defer:deferCreation])) {
-		[self setBackgroundColor:[NSColor clearColor]];
-		[self setMovableByWindowBackground:NO];
-		[self setExcludedFromWindowsMenu:YES];
-		[self setAlphaValue:1];
-		[self setOpaque:NO];
-		[self setHasShadow:YES];
-	}
-	return self;
-}
-
-- (BOOL) canBecomeKeyWindow {
-	return NO;
-}
-
-- (BOOL) canBecomeMainWindow {
-	return NO;
-}
-
-@end

+ 0 - 21
projects/Butterfly/Butterfly/Sources/BTFRulerView.h

@@ -1,21 +0,0 @@
-//
-//  BTFRulerView.h
-//  Butterfly
-//
-//  Created by Marco Bambini on 15/07/15.
-//  Copyright (c) 2015 Marco Bambini. All rights reserved.
-//
-
-#import <Cocoa/Cocoa.h>
-
-@class BTFTextView;
-@interface BTFRulerView : NSRulerView
-
-@property (nonatomic) NSColor *backgroundColor;
-@property (nonatomic) NSColor *textColor;
-@property (nonatomic) NSColor *borderColor;
-@property (nonatomic) CGFloat borderWidth;
-
-- (instancetype)initWithBTFTextView:(BTFTextView *)textView;
-
-@end

+ 0 - 150
projects/Butterfly/Butterfly/Sources/BTFRulerView.m

@@ -1,150 +0,0 @@
-//
-//  BTFRulerView.m
-//  Butterfly
-//
-//  Created by Marco Bambini on 15/07/15.
-//  Copyright (c) 2015 Marco Bambini. All rights reserved.
-//
-
-#import "BTFRulerView.h"
-#import "BTFTextView.h"
-
-#define BTF_RULER_WIDTH		40.0f
-#define BTF_RULER_PADDING	 5.0f
-
-#define MinX(FRAME)			CGRectGetMinX(FRAME)
-#define MinY(FRAME)			CGRectGetMinY(FRAME)
-#define MaxX(FRAME)			CGRectGetMaxX(FRAME)
-#define MaxY(FRAME)			CGRectGetMaxY(FRAME)
-
-static inline void drawLineNumberInRect(NSUInteger lineNumber, NSRect lineRect, NSDictionary *attributes, CGFloat ruleThickness) {
-	NSString *string = [[NSNumber numberWithUnsignedInteger:lineNumber] stringValue];
-	NSAttributedString *attString = [[NSAttributedString alloc] initWithString:string attributes:attributes];
-	NSUInteger x = ruleThickness - BTF_RULER_PADDING - attString.size.width;
-	
-	// Offsetting the drawing keeping into account the ascender (because we draw it without NSStringDrawingUsesLineFragmentOrigin)
-	NSFont *font = attributes[NSFontAttributeName];
-	lineRect.origin.x = x;
-	lineRect.origin.y += font.ascender;
-	
-	[attString drawWithRect:lineRect options:0 context:nil];
-}
-
-static inline NSUInteger countNewLines(NSString *s, NSUInteger location, NSUInteger length) {
-	CFStringInlineBuffer inlineBuffer;
-	CFStringInitInlineBuffer((__bridge CFStringRef)s, &inlineBuffer, CFRangeMake(location, length));
-	
-	NSUInteger counter = 0;
-	for (CFIndex i=0; i < length; ++i) {
-		UniChar c = CFStringGetCharacterFromInlineBuffer(&inlineBuffer, i);
-		if (c == (UniChar)'\n') ++counter;
-	}
-	return counter;
-}
-
-@implementation BTFRulerView
-
-- (instancetype)initWithBTFTextView:(BTFTextView *)textView {
-	self = [super initWithScrollView:textView.enclosingScrollView orientation:NSVerticalRuler];
-	if (self) {
-		self.clientView = textView;
-		
-		// default settings
-		self.ruleThickness = BTF_RULER_WIDTH;
-		self.textColor = [NSColor grayColor];
-	}
-	return self;
-}
-
-- (void)drawHashMarksAndLabelsInRect:(NSRect)rect {
-	// BACKGROUND
-	if (_backgroundColor) {
-		// do not use drawBackgroundInRect for background color otherwise a 1px right border with a different color appears
-		[_backgroundColor set];
-		[NSBezierPath fillRect:rect];
-	}
-		
-	if (_borderColor && _borderWidth > 0.0) {
-		NSBezierPath *borderBezierPath = [NSBezierPath bezierPath];
-		// LEFT
-		[borderBezierPath moveToPoint:NSMakePoint(NSMinX(rect), MinY(rect))];
-		[borderBezierPath lineToPoint:NSMakePoint(NSMinX(rect), MaxY(rect))];
-		
-		// RIGHT
-		[borderBezierPath moveToPoint:NSMakePoint(MaxX(rect), MinY(rect))];
-		[borderBezierPath lineToPoint:NSMakePoint(MaxX(rect), MaxY(rect))];
-		
-		[_borderColor setStroke];
-		[borderBezierPath setLineWidth:_borderWidth];
-		[borderBezierPath stroke];
-	}
-	
-	// MARKS AND LABELS
-	BTFTextView *textView = (BTFTextView *)self.clientView;
-	if (!textView) return;
-	
-	NSLayoutManager *layoutManager = textView.layoutManager;
-	if (!layoutManager) return;
-	
-	NSString *textString = textView.string;
-	if ((!textString) || (textString.length == 0)) return;
-	
-	CGFloat insetHeight = textView.textContainerInset.height;
-	CGPoint relativePoint = [self convertPoint:NSZeroPoint fromView:textView];
-	
-	// Gettign text attributes from the textview
-	NSMutableDictionary *lineNumberAttributes = [[textView.textStorage attributesAtIndex:0 effectiveRange:NULL] mutableCopy];
-	lineNumberAttributes[NSForegroundColorAttributeName] = self.textColor;
-	
-	NSRange visibleGlyphRange = [layoutManager glyphRangeForBoundingRect:textView.visibleRect inTextContainer:textView.textContainer];
-	NSUInteger firstVisibleGlyphCharacterIndex = [layoutManager characterIndexForGlyphAtIndex:visibleGlyphRange.location];
-	
-	// line number for the first visible line
-	NSUInteger lineNumber = countNewLines(textString, 0, firstVisibleGlyphCharacterIndex)+1;
-	NSUInteger glyphIndexForStringLine = visibleGlyphRange.location;
-	
-	// go through each line in the string
-	while (glyphIndexForStringLine < NSMaxRange(visibleGlyphRange)) {
-		// range of current line in the string
-		NSRange characterRangeForStringLine = [textString lineRangeForRange:NSMakeRange([layoutManager characterIndexForGlyphAtIndex:glyphIndexForStringLine], 0)];
-		NSRange glyphRangeForStringLine = [layoutManager glyphRangeForCharacterRange: characterRangeForStringLine actualCharacterRange:nil];
-		
-		NSUInteger glyphIndexForGlyphLine = glyphIndexForStringLine;
-		NSUInteger glyphLineCount = 0;
-		
-		while (glyphIndexForGlyphLine < NSMaxRange(glyphRangeForStringLine)) {
-			// check if the current line in the string spread across several lines of glyphs
-			NSRange effectiveRange = NSMakeRange(0, 0);
-			
-			// range of current "line of glyphs". If a line is wrapped then it will have more than one "line of glyphs"
-			NSRect lineRect = [layoutManager lineFragmentRectForGlyphAtIndex:glyphIndexForGlyphLine effectiveRange:&effectiveRange withoutAdditionalLayout:YES];
-			
-			// compute Y for line number
-			CGFloat y = ceil(NSMinY(lineRect) + relativePoint.y + insetHeight);
-			lineRect.origin.y = y;
-			
-			// draw line number only if string does not spread across several lines
-			if (glyphLineCount == 0) {
-				drawLineNumberInRect(lineNumber, lineRect, lineNumberAttributes, self.ruleThickness);
-			}
-			
-			// move to next glyph line
-			++glyphLineCount;
-			glyphIndexForGlyphLine = NSMaxRange(effectiveRange);
-		}
-		
-		glyphIndexForStringLine = NSMaxRange(glyphRangeForStringLine);
-		++lineNumber;
-	}
-	
-	// draw line number for the extra line at the end of the text
-	if (layoutManager.extraLineFragmentTextContainer) {
-		NSRect lineRect = layoutManager.extraLineFragmentRect;
-		CGFloat y = ceil(NSMinY(lineRect) + relativePoint.y + insetHeight);
-		lineRect.origin.y = y;
-		drawLineNumberInRect(lineNumber, lineRect, lineNumberAttributes, self.ruleThickness);
-	}
-}
-
-@end
-

+ 0 - 17
projects/Butterfly/Butterfly/Sources/BTFTextView.h

@@ -1,17 +0,0 @@
-//
-//  BTFTextView.h
-//  Butterfly
-//
-//  Created by Marco Bambini on 15/07/15.
-//  Copyright (c) 2015 Marco Bambini. All rights reserved.
-//
-
-#import <Cocoa/Cocoa.h>
-#import "BTFDelegate.h"
-#import "BTFRulerView.h"
-
-@interface BTFTextView : NSTextView
-@property (nonatomic, weak) id <BTFCodeEditorDelegate>	BTFDelegate;
-@property (nonatomic, weak) BTFRulerView				*rulerView;
-@property (nonatomic)		NSDictionary				*theme;
-@end

+ 0 - 526
projects/Butterfly/Butterfly/Sources/BTFTextView.m

@@ -1,526 +0,0 @@
-//
-//  BTFTextView.m
-//  Butterfly
-//
-//  Created by Marco Bambini on 15/07/15.
-//  Copyright (c) 2015 Marco Bambini. All rights reserved.
-//
-
-#import "BTFThemeKeys.h"
-#import "BTFTextView.h"
-#import "BTFPopover.h"
-#import "gravity_parser.h"
-
-#define BTF_DEFAULT_INSET_VALUE		10.0f
-#define BTF_MAX_RESULTS				10
-#define BTF_INTERCELL_SPACING		NSMakeSize(20.0f, 3.0f)
-#define BTF_DEFAULT_FONT			[NSFont fontWithName:@"Menlo" size:12.0f]
-#define BTF_DEFAULT_BOLDFONT		[NSFont fontWithName:@"Menlo-Bold" size:12.0f]
-
-#define BTF_POPOVER_DISTANCE		5.0f
-#define BTF_POPOVER_WIDTH			375.0f
-#define BTF_POPOVER_PADDING			0.0f
-#define BTF_POPOVER_FONT			BTF_DEFAULT_FONT
-#define BTF_POPOVER_BOLDFOND		BTF_DEFAULT_BOLDFONT
-#define BTF_POPOVER_TEXTCOLOR		[NSColor blackColor]
-
-#define BTF_HIGHLIGHT_STROKE_COLOR	[NSColor selectedMenuItemColor]
-#define BTF_HIGHLIGHT_FILL_COLOR	[NSColor selectedMenuItemColor]
-#define BTF_HIGHLIGHT_RADIUS		0.0f
-
-#pragma mark -
-
-@interface BTFAutocompleteTableRowView : NSTableRowView
-@end
-@implementation BTFAutocompleteTableRowView
-- (void)drawSelectionInRect:(NSRect)dirtyRect {
-	if (self.selectionHighlightStyle != NSTableViewSelectionHighlightStyleNone) {
-		NSRect selectionRect = NSInsetRect(self.bounds, 0.5, 0.5);
-		[BTF_HIGHLIGHT_STROKE_COLOR setStroke];
-		[BTF_HIGHLIGHT_FILL_COLOR setFill];
-		NSBezierPath *selectionPath = [NSBezierPath bezierPathWithRoundedRect:selectionRect xRadius:BTF_HIGHLIGHT_RADIUS yRadius:BTF_HIGHLIGHT_RADIUS];
-		[selectionPath fill];
-		[selectionPath stroke];
-	}
-}
-- (NSBackgroundStyle)interiorBackgroundStyle {
-	if (self.isSelected) {
-		return NSBackgroundStyleDark;
-	} else {
-		return NSBackgroundStyleLight;
-	}
-}
-@end
-
-#pragma mark -
-
-@interface BTFTextView() <NSTableViewDataSource, NSTableViewDelegate, NSTextViewDelegate, NSTextDelegate> {
-	BTFPopover			*autocompletePopover;
-	NSTableView			*autocompleteTableView;
-	BOOL				autocompleteSupported;
-	NSCharacterSet		*characterSet;
-	
-	NSArray				*matches;
-	NSString			*substring;
-	NSInteger			lastPosition;
-	NSDictionary		*theme;
-	
-	NSFont				*fontRegular;
-	NSFont				*fontBold;
-	
-	gravity_delegate_t	compiler_delegate;
-}
-@end
-
-static void	errorCallback (error_type_t error_type, const char *description, error_desc_t error_desc, void *xdata) {
-//	BTFTextView *textView = (__bridge BTFTextView *)xdata;
-//	
-//	const char *type = "N/A";
-//	switch (error_type) {
-//		case GRAVITY_ERROR_NONE: type = "NONE"; break;
-//		case GRAVITY_ERROR_SYNTAX: type = "SYNTAX"; break;
-//		case GRAVITY_ERROR_SEMANTIC: type = "SEMANTIC"; break;
-//		case GRAVITY_ERROR_IO: type = "I/O"; break;
-//		case GRAVITY_ERROR_RUNTIME: type = "RUNTIME"; break;
-//		case GRAVITY_WARNING: type = "WARNING"; break;
-//	}
-//	
-//	if (error_type == GRAVITY_ERROR_RUNTIME) printf("RUNTIME ERROR: ");
-//	else printf("%s ERROR (code %d) on %s (%d,%d)\n", type, error_desc.error_code, error_desc.filename, error_desc.lineno, error_desc.colno);
-//	printf("%s\n", description);
-}
-
-static void parserCallback (void *xtoken, void *xdata) {
-	BTFTextView		*textView = (__bridge BTFTextView *) xdata;
-	NSDictionary	*theme = textView.theme;
-	gtoken_s		*token = (gtoken_s *)xtoken;
-	
-	[textView.textStorage beginEditing];
-	NSRange range = NSMakeRange(token->position, token->length);
-	@try {
-		switch (token->type) {
-			case TOK_COMMENT:
-				[textView setTextColor:theme[BTFKEY_COMMENTS_COLOR] range:range];
-				break;
-				
-			case TOK_IDENTIFIER:
-				[textView setTextColor:theme[BTFKEY_PLAIN_COLOR] range:range];
-				break;
-			
-			case TOK_MACRO:
-			case TOK_KEY_IMPORT:
-				[textView setTextColor:theme[BTFKEY_MACROS_COLOR] range:range];
-				break;
-			
-			case TOK_KEY_ENUM:
-			case TOK_KEY_MODULE:
-			case TOK_KEY_VAR:
-			case TOK_KEY_CONST:
-			case TOK_KEY_CLASS:
-			case TOK_KEY_FUNC:
-			case TOK_KEY_SUPER:
-			case TOK_KEY_DEFAULT:
-			case TOK_KEY_TRUE:
-			case TOK_KEY_FALSE:
-			case TOK_KEY_IF:
-			case TOK_KEY_ELSE:
-			case TOK_KEY_SWITCH:
-			case TOK_KEY_BREAK:
-			case TOK_KEY_CONTINUE:
-			case TOK_KEY_RETURN:
-			case TOK_KEY_WHILE:
-			case TOK_KEY_REPEAT:
-			case TOK_KEY_FOR:
-			case TOK_KEY_IN:
-			case TOK_KEY_PRIVATE:
-			case TOK_KEY_INTERNAL:
-			case TOK_KEY_PUBLIC:
-			case TOK_KEY_STATIC:
-			case TOK_KEY_EXTERN:
-			case TOK_KEY_CASE:
-			case TOK_KEY_EVENT:
-			case TOK_KEY_FILE:
-			case TOK_KEY_NULL:
-			case TOK_KEY_UNDEFINED:
-			case TOK_KEY_CURRARGS:
-				[textView setTextColor:theme[BTFKEY_KEYWORDS_COLOR] range:range];
-				break;
-				
-			case TOK_STRING:
-				// in case of literal string, returned token is the string itself and
-				// not the string surronded by the quotes, so let's fix it!
-				range.location-=1; range.length+=2;
-				[textView setTextColor:theme[BTFKEY_STRINGS_COLOR] range:range];
-				break;
-				
-			case TOK_NUMBER:
-				[textView setTextColor:theme[BTFKEY_NUMBERS_COLOR] range:range];
-				break;
-				
-			case TOK_SPECIAL:
-				[textView setTextColor:theme[BTFKEY_SPECIAL_COLOR] range:range];
-				break;
-				
-			case TOK_ERROR: {
-				[textView setTextColor:theme[BTFKEY_PLAIN_COLOR] range:range];
-				}
-				break;
-				
-			default:
-				[textView setTextColor:theme[BTFKEY_PLAIN_COLOR] range:range];
-				break;
-		}		
-	}
-	@catch (NSException *exception) {
-		NSLog(@"%@", exception.reason);
-	}
-	@finally {
-		//NSLog(@"(%d, %d)\t%s\t%@", token->lineno, token->colno, token_name(token->type), NSStringFromRange(range));
-		//NSLog(@"%@", [textView.string substringWithRange:range]);
-		[textView.textStorage endEditing];
-	}
-}
-
-static BOOL is_word_boundary (unichar c) {
-	if (c == '_') return NO;
-	if (isspace(c)) return YES;
-	if (iscntrl(c)) return YES;
-	if (ispunct(c)) return YES;
-	return NO;
-}
-
-@implementation BTFTextView
-
-- (instancetype)initWithFrame:(NSRect)frameRect textContainer:(NSTextContainer *)aTextContainer {
-	self = [super initWithFrame:frameRect textContainer:aTextContainer];
-	if (self) {
-		// default TextView settings
-		[self setTextContainerInset:NSMakeSize(BTF_DEFAULT_INSET_VALUE, BTF_DEFAULT_INSET_VALUE)];
-		[self setFont:BTF_DEFAULT_FONT];
-		[self setRichText:YES];
-		
-		[self setAutomaticTextReplacementEnabled:NO];
-		[self setAutomaticSpellingCorrectionEnabled:NO];
-		[self setAutomaticDataDetectionEnabled:NO];
-		[self setAutomaticDashSubstitutionEnabled:NO];
-		[self setEnabledTextCheckingTypes:NO];
-		
-		[self setDelegate:self];
-		[self setUpAutocompletion];
-		characterSet = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
-		
-		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidEndEditing:)
-													 name:NSControlTextDidEndEditingNotification object:nil];
-		
-		self.allowsUndo = YES;
-		
-		compiler_delegate.xdata = (__bridge void *)(self);
-		compiler_delegate.parser_callback = parserCallback;
-		compiler_delegate.error_callback = errorCallback;
-	}
-	return self;
-}
-
-- (void) dealloc {
-	[[NSNotificationCenter defaultCenter] removeObserver:self name:NSControlTextDidEndEditingNotification object:nil];
-}
-
-- (void) setTheme:(NSDictionary *)aTheme {
-	// process keys that need to be always evaluated (it should work for NSString {v1,v2}
-	if (aTheme[BTFKEY_INSET_VALUE]) [self setTextContainerInset:[aTheme[BTFKEY_INSET_VALUE] sizeValue]];
-	if (aTheme[BTFKEY_BACKGROUND_COLOR]) [self setBackgroundColor:aTheme[BTFKEY_BACKGROUND_COLOR]];
-	if (aTheme[BTFKEY_SELECTION_COLOR]) [self setSelectedTextAttributes:@{NSBackgroundColorAttributeName:aTheme[BTFKEY_SELECTION_COLOR]}];
-	if (aTheme[BTFKEY_CURSOR_COLOR]) [self setInsertionPointColor:aTheme[BTFKEY_CURSOR_COLOR]];
-	if (aTheme[BTFKEY_FONT]) [self setFont:aTheme[BTFKEY_FONT]];
-	if (aTheme[BTFKEY_PLAIN_COLOR]) [self setTextColor:aTheme[BTFKEY_PLAIN_COLOR]];
-	theme = aTheme;
-}
-
-- (NSDictionary *)theme {
-	return theme;
-}
-
-- (void) setUpAutocompletion {
-	// Make a table view with 1 column and enclosing scroll view. It doesn't
-	// matter what the frames are here because they are set when the popover
-	// is displayed
-	NSTableColumn *column1 = [[NSTableColumn alloc] initWithIdentifier:@"text"];
-	[column1 setEditable:NO];
-	[column1 setWidth:BTF_POPOVER_WIDTH - 2 * BTF_POPOVER_PADDING];
-	
-	NSTableView *tableView = [[NSTableView alloc] initWithFrame:NSZeroRect];
-	[tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleRegular];
-	[tableView setBackgroundColor:[NSColor clearColor]];
-	[tableView setRowSizeStyle:NSTableViewRowSizeStyleSmall];
-	[tableView setIntercellSpacing:BTF_INTERCELL_SPACING];
-	[tableView setHeaderView:nil];
-	[tableView setRefusesFirstResponder:YES];
-	[tableView setTarget:self];
-	[tableView setDoubleAction:@selector(insert:)];
-	[tableView addTableColumn:column1];
-	[tableView setDelegate:self];
-	[tableView setDataSource:self];
-	autocompleteTableView = tableView;
-	
-	NSScrollView *tableScrollView = [[NSScrollView alloc] initWithFrame:NSZeroRect];
-	[tableScrollView setDrawsBackground:NO];
-	[tableScrollView setDocumentView:tableView];
-	[tableScrollView setHasVerticalScroller:YES];
-		
-	// Setup custom popover
-	autocompletePopover = [[BTFPopover alloc] initWithContentView:tableScrollView];
-	
-	// Finish setup
-	matches = @[];
-	lastPosition = -1;
-	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeSelection:) name:@"NSTextViewDidChangeSelectionNotification" object:nil];
-}
-
--(void)setString:(NSString *)aString {
-	[super setString:aString];
-	#pragma clang diagnostic push
-	#pragma clang diagnostic ignored "-Wnonnull"
-	[self textDidChange:nil];
-	#pragma clang diagnostic pop
-}
-
-- (void)textDidChange:(NSNotification*)notification {
-	NSString *code = [self string];
-	NSRange range = NSMakeRange(0, [code length]);
-	
-	[self setTextColor:theme[BTFKEY_PLAIN_COLOR] range:range];
-	// DO NOT USE [code lenght] here, otherwise UTF-8 characters are not counted!
-	gravity_parser_t *parser = gravity_parser_create([code UTF8String], [code lengthOfBytesUsingEncoding:NSUTF8StringEncoding], 0, true);
-	gravity_parser_run(parser, &compiler_delegate);
-	gravity_parser_free(parser);
-}
-
-- (void)textDidEndEditing:(NSNotification *)notification {
-	if (!self.BTFDelegate) return;
-	if ([self.BTFDelegate respondsToSelector:@selector(textDidEndEditing:)]) {
-		[self.BTFDelegate textDidEndEditing:self];
-	}
-}
-
-- (void)setBTFDelegate:(id<BTFCodeEditorDelegate>)aBTFDelegate {
-	_BTFDelegate = aBTFDelegate;
-	autocompleteSupported = [self.BTFDelegate respondsToSelector:@selector(textView:completions:forPartialWordRange:location:indexOfSelectedItem:)];
-}
-
-#pragma mark - Autocompletion -
-
-- (void)keyDown:(NSEvent *)theEvent {
-	NSInteger row = autocompleteTableView.selectedRow;
-	BOOL shouldComplete = YES;
-	
-	switch (theEvent.keyCode) {
-		case 51:	// Delete key
-			[autocompletePopover closePopover:self];
-			break;
-		case 53:	// Esc key
-			if (autocompletePopover.isVisible)
-				[autocompletePopover closePopover:self];
-			return; // Skip default behavior
-		case 125:	// Down arrow
-			if (autocompletePopover.isVisible) {
-				[autocompleteTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:row+1] byExtendingSelection:NO];
-				[autocompleteTableView scrollRowToVisible:autocompleteTableView.selectedRow];
-				return; // Skip default behavior
-			}
-			break;
-		case 126:	// Up arrow
-			if (autocompletePopover.isVisible) {
-				[autocompleteTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:row-1] byExtendingSelection:NO];
-				[autocompleteTableView scrollRowToVisible:autocompleteTableView.selectedRow];
-				return; // Skip default behavior
-			}
-			break;
-		case 36:	// Return key
-		case 48:	// Tab key
-			if (autocompletePopover.isVisible) {
-				[self insert:self];
-				return; // Skip default behavior
-			}
-		case 124:	// Right arrow
-		case 123:	// Left arrow
-		case 49:	// Space key
-			if (autocompletePopover.isVisible) {
-				[autocompletePopover closePopover:self];
-			}
-			break;
-	}
-
-	[super keyDown:theEvent];
-	if (shouldComplete) {
-		[self complete:self];
-	}
-}
-
-- (void)didChangeSelection:(NSNotification *)notification {
-	if ((self.selectedRange.location - lastPosition) > 1) {
-		// if selection moves by more than just one character, hide autocomplete
-		[autocompletePopover closePopover:self];
-	}
-}
-
-- (void)paste:(id)sender {
-	[self pasteAsPlainText:sender];
-	[self complete:nil];
-}
-
-- (void)copy:(id)sender {
-	NSRange range = self.selectedRange;
-	NSString *text = (range.location != NSNotFound) ? [self.string substringWithRange:self.selectedRange] : self.string;
-	NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
-	[pasteBoard declareTypes:[NSArray arrayWithObjects:NSStringPboardType, nil] owner:nil];
-	[pasteBoard setString:text forType:NSStringPboardType];
-}
-
-- (void)insert:(id)sender {
-	if (autocompleteTableView.selectedRow >= 0 && autocompleteTableView.selectedRow < matches.count) {
-		NSString *string = [matches objectAtIndex:autocompleteTableView.selectedRow];
-		NSInteger beginningOfWord = self.selectedRange.location - substring.length;
-		NSRange range = NSMakeRange(beginningOfWord, substring.length);
-		if ([self shouldChangeTextInRange:range replacementString:string]) {
-			[self replaceCharactersInRange:range withString:string];
-			[self didChangeText];
-		}
-	}
-	[autocompletePopover closePopover:self];
-}
-
-- (void)complete:(id)sender {
-	NSInteger startOfWord = self.selectedRange.location;
-	
-	// extract member access (if any) Navigation1.Window1.Label1.text
-	NSMutableArray *completions = [NSMutableArray array];
-	NSInteger dotIndex = 0;
-	for (NSInteger i = startOfWord - 1; i >= 0; --i) {
-		unichar c = [self.string characterAtIndex:i];
-		if (c == '.') {
-			// check if it is a multi member case
-			if (dotIndex != 0) {
-				NSString *member = [self.string substringWithRange:NSMakeRange(i+1, dotIndex-(i+1))];
-				if ((member == nil) || member.length == 0) {[completions removeAllObjects]; break;}
-				[completions addObject:member];
-			}
-			dotIndex = i;
-			continue;
-		}
-		
-		// member access lookup break condition
-		BOOL isBoundary = is_word_boundary(c);
-		if (isBoundary && dotIndex == 0) break;
-		
-		// member case
-		if (((i == 0) || isBoundary) && dotIndex != 0) {
-			NSString *member = [self.string substringWithRange:NSMakeRange(i, dotIndex-i)];
-			if ((member == nil) || member.length == 0) {[completions removeAllObjects]; break;}
-			[completions addObject:member];
-			dotIndex = 0;
-		}
-	}
-	
-	// extract current word
-	for (NSInteger i = startOfWord - 1; i >= 0; --i) {
-		if ([characterSet characterIsMember:[self.string characterAtIndex:i]]) break;
-		--startOfWord;
-	}
-	
-	// extract current lenght
-	NSInteger lengthOfWord = 0;
-	for (NSInteger i = startOfWord; i < self.string.length; ++i) {
-		if ([characterSet characterIsMember:[self.string characterAtIndex:i]]) break;
-		++lengthOfWord;
-	}
-	
-	substring = [self.string substringWithRange:NSMakeRange(startOfWord, lengthOfWord)];
-	NSRange substringRange = NSMakeRange(startOfWord, self.selectedRange.location - startOfWord);
-	
-	// NSLog(@"%@ %ld %ld %lu", substring, (long)startOfWord, (long)lengthOfWord, (unsigned long)self.selectedRange.location);
-	
-	// This happens when we just started a new word or if we have already typed the entire word
-	if ((substringRange.length == 0 || lengthOfWord == 0) && (completions.count == 0)) {
-		[autocompletePopover closePopover:self];
-		return;
-	}
-	
-	NSInteger index = 0;
-	if (autocompleteSupported) {
-		NSArray *r = [[completions reverseObjectEnumerator] allObjects];
-		matches = [self.BTFDelegate textView:self completions:r forPartialWordRange:substringRange
-									location:self.selectedRange.location indexOfSelectedItem:&index];
-	} else matches = @[];
-	
-	if (matches.count > 0) {
-		lastPosition = self.selectedRange.location;
-		[autocompleteTableView reloadData];
-		
-		[autocompleteTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:index] byExtendingSelection:NO];
-		[autocompleteTableView scrollRowToVisible:index];
-		
-		// Make the frame for the popover. We want it to shrink with a small number
-		// of items to autocomplete but never grow above a certain limit when there
-		// are a lot of items. The limit is set by MAX_RESULTS.
-		NSInteger numberOfRows = MIN(autocompleteTableView.numberOfRows, BTF_MAX_RESULTS);
-		CGFloat height = (autocompleteTableView.rowHeight + autocompleteTableView.intercellSpacing.height) * numberOfRows + 2 * BTF_POPOVER_PADDING;
-		NSRect frame = NSMakeRect(0, 0, BTF_POPOVER_WIDTH, height);
-		[autocompleteTableView.enclosingScrollView setFrame:NSInsetRect(frame, BTF_POPOVER_PADDING, BTF_POPOVER_PADDING)];
-		[[autocompletePopover window] setContentSize:NSMakeSize(NSWidth(frame), NSHeight(frame))];
-		
-		// Find best coord to display the popover
-		NSRect rect = [self firstRectForCharacterRange:substringRange actualRange:NULL];
-		rect.origin.y -= (height + BTF_POPOVER_DISTANCE);
-		
-		[autocompletePopover displayPopoverInWindow:self.window	atPoint:rect.origin];
-	} else {
-		[autocompletePopover closePopover:self];
-	}
-}
-
-#pragma mark - NSTableView Data Source -
-
-- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
-	return matches.count;
-}
-
-- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
-	NSTableCellView *cellView = [tableView makeViewWithIdentifier:@"BTFCellView" owner:self];
-	if (cellView == nil) {
-		cellView = [[NSTableCellView alloc] initWithFrame:NSZeroRect];
-		NSTextField *textField = [[NSTextField alloc] initWithFrame:NSZeroRect];
-		[textField setBezeled:NO];
-		[textField setDrawsBackground:NO];
-		[textField setEditable:NO];
-		[textField setSelectable:NO];
-		[cellView addSubview:textField];
-		cellView.textField = textField;
-//		if ([self.BTFDelegate respondsToSelector:@selector(textView:imageForCompletion:)]) {
-//			NSImageView *imageView = [[NSImageView alloc] initWithFrame:NSZeroRect];
-//			[imageView setImageFrameStyle:NSImageFrameNone];
-//			[imageView setImageScaling:NSImageScaleNone];
-//			[cellView addSubview:imageView];
-//			cellView.imageView = imageView;
-//		}
-		
-		cellView.identifier = @"BTFCellView";
-	}
-	
-	NSDictionary *attributes = @{NSFontAttributeName:BTF_POPOVER_FONT, NSForegroundColorAttributeName:BTF_POPOVER_TEXTCOLOR};
-	NSMutableAttributedString *s = [[NSMutableAttributedString alloc] initWithString:matches[row] attributes:attributes];
-	
-	if (substring) {
-		NSRange range = [s.string rangeOfString:substring options:NSAnchoredSearch|NSCaseInsensitiveSearch];
-		[s addAttribute:NSFontAttributeName value:BTF_POPOVER_BOLDFOND range:range];
-	}
-	
-	[cellView.textField setAttributedStringValue:s];
-	return cellView;
-}
-
-- (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row {
-	return [[BTFAutocompleteTableRowView alloc] init];
-}
-
-@end
-

+ 0 - 54
projects/Butterfly/Butterfly/Sources/BTFThemeKeys.h

@@ -1,54 +0,0 @@
-//
-//  BTFThemeKeys.h
-//  Butterfly
-//
-//  Created by Marco Bambini on 15/07/15.
-//  Copyright (c) 2015 Marco Bambini. All rights reserved.
-//
-
-// HEADER
-#define BTFKEY_HEADER_BORDER_COLOR			@"HEADER_BORDER_COLOR"
-#define BTFKEY_HEADER_BACKGROUND_COLOR		@"HEADER_BACKGROUND_COLOR"
-#define BTFKEY_HEADER_DETACH_IMAGE			@"HEADER_DETACH_IMAGE"
-#define BTFKEY_HEADER_ATTACH_IMAGE			@"HEADER_ATTACH_IMAGE"
-
-// NAVIGATION
-#define BTFKEY_NAV_TEXT_COLOR				@"NAVIGATION_TEXTPLAIN_COLOR"
-#define BTFKEY_NAV_BOLD_COLOR				@"NAVIGATION_TEXTBOLD_COLOR"
-#define BTFKEY_NAV_SELECTION_COLOR			@"NAVIGATION_SELECTION_COLOR"
-#define BTFKEY_NAV_BACKGROUND_COLOR			@"NAVIGATION_BACKGROUND_COLOR"
-
-// RULER
-#define BTFKEY_RULER_BACKGROUND_COLOR		@"RULER_BACKGROUND_COLOR"
-#define BTFKEY_RULER_TEXT_COLOR				@"RULER_TEXTPLAIN_COLOR"
-#define BTFKEY_RULER_ERROR_COLOR			@"RULER_TEXTERROR_COLOR"
-#define BTFKEY_RULER_BORDER_COLOR			@"RULER_BORDER_COLOR"
-#define BTFKEY_RULER_BORDER_WIDTH			@"RULER_BORDER_WIDTH"
-#define BTFKEY_RULER_WIDTH					@"RULER_WIDTH"
-
-// SCOPE
-#define BTFKEY_SCOPE_ALPHA					@"SCOPE_ALPHA"
-
-// CODEEDITOR
-#define BTFKEY_INSET_VALUE					@"CODEEDITOR_INSET_VALUE"
-#define BTFKEY_BACKGROUND_COLOR				@"CODEEDITOR_BACKGROUND_COLOR"
-#define BTFKEY_FONT							@"CODEEDITOR_PLAIN_FONT"
-#define BTFKEY_BOLD_FONT					@"CODEEDITOR_BOLD_FONT"
-#define BTFKEY_FONT_SIZE					@"CODEEDITOR_FONT_SIZE"
-#define BTFKEY_SELECTION_COLOR				@"CODEEDITOR_SELECTION_COLOR"
-#define BTFKEY_CURSOR_COLOR					@"CODEEDITOR_CURSOR_COLOR"
-#define BTFKEY_PLAIN_COLOR					@"CODEEDITOR_PLAIN_COLOR"
-#define BTFKEY_IDENTIFIER_COLOR				@"CODEEDITOR_IDENTIFIER_COLOR"
-#define BTFKEY_COMMENTS_COLOR				@"CODEEDITOR_COMMENTS_COLOR"
-#define BTFKEY_STRINGS_COLOR				@"CODEEDITOR_STRINGS_COLOR"
-#define BTFKEY_NUMBERS_COLOR				@"CODEEDITOR_NUMBERS_COLOR"
-#define BTFKEY_KEYWORDS_COLOR				@"CODEEDITOR_KEYWORDS_COLOR"
-#define BTFKEY_MACROS_COLOR					@"CODEEDITOR_MACROS_COLOR"
-#define BTFKEY_SPECIAL_COLOR				@"CODEEDITOR_SPECIAL_COLOR"
-#define BTFKEY_CLASS_COLOR					@"CODEEDITOR_CLASS_COLOR"
-#define BTFKEY_FUNCTION_COLOR				@"CODEEDITOR_FUNCTION_COLOR"
-#define BTFKEY_VAR_COLOR					@"CODEEDITOR_VAR_COLOR"
-#define BTFKEY_CONST_COLOR					@"CODEEDITOR_CONST_COLOR"
-#define BTFKEY_ENUM_COLOR					@"CODEEDITOR_ENUM_COLOR"
-#define BTFKEY_MODULES_COLOR				@"CODEEDITOR_MODULES_COLOR"
-#define BTFKEY_ERROR_COLOR					@"CODEEDITOR_ERROR_COLOR"

+ 0 - 13
projects/Butterfly/Butterfly/main.m

@@ -1,13 +0,0 @@
-//
-//  main.m
-//  Butterfly
-//
-//  Created by Marco Bambini on 18/03/2017.
-//  Copyright © 2017 Creolabs. All rights reserved.
-//
-
-#import <Cocoa/Cocoa.h>
-
-int main(int argc, const char * argv[]) {
-	return NSApplicationMain(argc, argv);
-}

+ 0 - 36
projects/Butterfly/Themes/Fourier.theme

@@ -1,36 +0,0 @@
-{
-	"HEADER_BORDER_COLOR": "#BEBEBE",
-	"HEADER_BACKGROUND_COLOR": "#FFFEF5",
-	"HEADER_DETACH_IMAGE": "CodeEditorDetach",
-	"HEADER_ATTACH_IMAGE": "CodeEditorAttach",
-	"NAVIGATION_TEXTPLAIN_COLOR": "#454545",
-	"NAVIGATION_TEXTBOLD_COLOR": "#454545",
-	"NAVIGATION_SELECTION_COLOR": "#E2F0FC",
-	"NAVIGATION_BACKGROUND_COLOR": "#FFFEF5",
-	"RULER_BACKGROUND_COLOR": "#F7F4E2",
-	"RULER_TEXTPLAIN_COLOR": "#636363",
-	"RULER_BORDER_COLOR": "#979797",
-	"RULER_BORDER_WIDTH": 0.5,
-	"SCOPE_ALPHA": 1.0,
-	"CODEEDITOR_BACKGROUND_COLOR":"#FFFEF5",
-	"CODEEDITOR_SELECTION_COLOR": "#E2F0FC",
-	"CODEEDITOR_PLAIN_COLOR": "#000000",
-	"CODEEDITOR_IDENTIFIER_COLOR": "#000000",
-	"CODEEDITOR_CURSOR_COLOR": "#000000",
-	"CODEEDITOR_COMMENTS_COLOR": "#758F7E",
-	"CODEEDITOR_STRINGS_COLOR": "#FFAC02",
-	"CODEEDITOR_NUMBERS_COLOR": "#31CA41",
-	"CODEEDITOR_KEYWORDS_COLOR": "#FF2600",
-	"CODEEDITOR_MACROS_COLOR": "#CA45B3",
-	"CODEEDITOR_SPECIAL_COLOR": "#CA45B3",
-	"CODEEDITOR_CLASS_COLOR": "#FF0202",
-	"CODEEDITOR_FUNCTION_COLOR": "#FF0202",
-	"CODEEDITOR_VAR_COLOR": "#FF2600",
-	"CODEEDITOR_CONST_COLOR": "#FF2600",
-	"CODEEDITOR_ENUM_COLOR": "#FF2600",
-	"CODEEDITOR_MODULES_COLOR": "#FF2600",
-	"CODEEDITOR_ERROR_COLOR": "#000000",
-	"CODEEDITOR_PLAIN_FONT": "Menlo-Regular",
-	"CODEEDITOR_BOLD_FONT": "Menlo-Bold",
-	"CODEEDITOR_FONT_SIZE": 13
-}

+ 0 - 34
projects/Butterfly/Themes/Gauss.theme

@@ -1,34 +0,0 @@
-{
-	"HEADER_BORDER_COLOR": "#4B4B4B",
-	"HEADER_BACKGROUND_COLOR": "#212224",
-	"HEADER_DETACH_IMAGE": "CodeEditorDetachWhite",
-	"HEADER_ATTACH_IMAGE": "CodeEditorAttachWhite",	
-	"NAVIGATION_TEXTPLAIN_COLOR": "#888A8F",
-	"NAVIGATION_TEXTBOLD_COLOR": "#FFFFFF",
-	"NAVIGATION_SELECTION_COLOR": "#424244",
-	"NAVIGATION_BACKGROUND_COLOR": "#212224",
-	"RULER_BACKGROUND_COLOR": "#141414",
-	"RULER_TEXTPLAIN_COLOR": "#55575B",
-	"SCOPE_ALPHA": 0.8,
-	"CODEEDITOR_BACKGROUND_COLOR":"#212224",
-	"CODEEDITOR_SELECTION_COLOR": "#68634D",
-	"CODEEDITOR_PLAIN_COLOR": "#FFFFFF",
-	"CODEEDITOR_IDENTIFIER_COLOR": "#FFFFFF",
-	"CODEEDITOR_CURSOR_COLOR": "#FFFFFF",
-	"CODEEDITOR_COMMENTS_COLOR": "#666666",
-	"CODEEDITOR_STRINGS_COLOR": "#DD2249",
-	"CODEEDITOR_NUMBERS_COLOR": "#786DFF",
-	"CODEEDITOR_KEYWORDS_COLOR": "#00E475",
-	"CODEEDITOR_MACROS_COLOR": "#AAAAAA",
-	"CODEEDITOR_SPECIAL_COLOR": "#AAAAAA",
-	"CODEEDITOR_CLASS_COLOR": "#FF00DF",
-	"CODEEDITOR_FUNCTION_COLOR": "#FF00DF",
-	"CODEEDITOR_VAR_COLOR": "#00E475",
-	"CODEEDITOR_CONST_COLOR": "#00E475",
-	"CODEEDITOR_ENUM_COLOR": "#005BF1",
-	"CODEEDITOR_MODULES_COLOR": "#005BF1",
-	"CODEEDITOR_ERROR_COLOR": "#888A8F",
-	"CODEEDITOR_PLAIN_FONT": "Menlo-Regular",
-	"CODEEDITOR_BOLD_FONT": "Menlo-Bold",
-	"CODEEDITOR_FONT_SIZE": 13
-}

+ 0 - 36
projects/Butterfly/Themes/Laplace.theme

@@ -1,36 +0,0 @@
-{
-	"HEADER_BORDER_COLOR": "#BEBEBE",
-	"HEADER_BACKGROUND_COLOR": "#FFFFFF",
-	"HEADER_DETACH_IMAGE": "CodeEditorDetach",
-	"HEADER_ATTACH_IMAGE": "CodeEditorAttach",	
-	"NAVIGATION_TEXTPLAIN_COLOR": "#454545",
-	"NAVIGATION_TEXTBOLD_COLOR": "#454545",
-	"NAVIGATION_SELECTION_COLOR": "#E2F0FC",
-	"NAVIGATION_BACKGROUND_COLOR": "#FFFFFF",
-	"RULER_BACKGROUND_COLOR": "#F7F7F7",
-	"RULER_TEXTPLAIN_COLOR": "#636363",
-	"RULER_BORDER_COLOR": "#979797",
-	"RULER_BORDER_WIDTH": 0.5,
-	"SCOPE_ALPHA": 1.0,
-	"CODEEDITOR_BACKGROUND_COLOR":"#FFFFFF",
-	"CODEEDITOR_SELECTION_COLOR": "#E2F0FC",
-	"CODEEDITOR_PLAIN_COLOR": "#000000",
-	"CODEEDITOR_IDENTIFIER_COLOR": "#000000",
-	"CODEEDITOR_CURSOR_COLOR": "#000000",
-	"CODEEDITOR_COMMENTS_COLOR": "#00852C",
-	"CODEEDITOR_STRINGS_COLOR": "#DE4205",
-	"CODEEDITOR_NUMBERS_COLOR": "#3047E4",
-	"CODEEDITOR_KEYWORDS_COLOR": "#CA45B3",
-	"CODEEDITOR_MACROS_COLOR": "#CA45B3",
-	"CODEEDITOR_SPECIAL_COLOR": "#CA45B3",
-	"CODEEDITOR_CLASS_COLOR": "#CA45B3",
-	"CODEEDITOR_FUNCTION_COLOR": "#CA45B3",
-	"CODEEDITOR_VAR_COLOR": "#CA45B3",
-	"CODEEDITOR_CONST_COLOR": "#CA45B3",
-	"CODEEDITOR_ENUM_COLOR": "#CA45B3",
-	"CODEEDITOR_MODULES_COLOR": "#CA45B3",
-	"CODEEDITOR_ERROR_COLOR": "#000000",
-	"CODEEDITOR_PLAIN_FONT": "Menlo-Regular",
-	"CODEEDITOR_BOLD_FONT": "Menlo-Bold",
-	"CODEEDITOR_FONT_SIZE": 13
-}

+ 0 - 34
projects/Butterfly/Themes/Riemann.theme

@@ -1,34 +0,0 @@
-{
-	"HEADER_BORDER_COLOR": "#4B4B4B",
-	"HEADER_BACKGROUND_COLOR": "#1A1F29",
-	"HEADER_DETACH_IMAGE": "CodeEditorDetachWhite",
-	"HEADER_ATTACH_IMAGE": "CodeEditorAttachWhite",	
-	"NAVIGATION_TEXTPLAIN_COLOR": "#888A8F",
-	"NAVIGATION_TEXTBOLD_COLOR": "#FFFFFF",
-	"NAVIGATION_SELECTION_COLOR": "#424244",
-	"NAVIGATION_BACKGROUND_COLOR": "#1A1F29",
-	"RULER_BACKGROUND_COLOR": "#10151E",
-	"RULER_TEXTPLAIN_COLOR": "#55575B",
-	"SCOPE_ALPHA": 0.8,
-	"CODEEDITOR_BACKGROUND_COLOR":"#1A1F29",
-	"CODEEDITOR_SELECTION_COLOR": "#68634D",
-	"CODEEDITOR_PLAIN_COLOR": "#FFFFFF",
-	"CODEEDITOR_IDENTIFIER_COLOR": "#FFFFFF",
-	"CODEEDITOR_CURSOR_COLOR": "#FFFFFF",
-	"CODEEDITOR_COMMENTS_COLOR": "#797979",
-	"CODEEDITOR_STRINGS_COLOR": "#12D2EF",
-	"CODEEDITOR_NUMBERS_COLOR": "#00FA41",
-	"CODEEDITOR_KEYWORDS_COLOR": "#FFB532",
-	"CODEEDITOR_MACROS_COLOR": "#AAAAAA",
-	"CODEEDITOR_SPECIAL_COLOR": "#AAAAAA",
-	"CODEEDITOR_CLASS_COLOR": "#FF9800",
-	"CODEEDITOR_FUNCTION_COLOR": "#FF9800",
-	"CODEEDITOR_VAR_COLOR": "#FEA727",
-	"CODEEDITOR_CONST_COLOR": "#FEA727",
-	"CODEEDITOR_ENUM_COLOR": "#FEA727",
-	"CODEEDITOR_MODULES_COLOR": "#FEA727",
-	"CODEEDITOR_ERROR_COLOR": "#C31717",
-	"CODEEDITOR_PLAIN_FONT": "Menlo-Regular",
-	"CODEEDITOR_BOLD_FONT": "Menlo-Bold",
-	"CODEEDITOR_FONT_SIZE": 13
-}

BIN
projects/Butterfly/screenshot.png


+ 0 - 11
projects/README.md

@@ -1,11 +0,0 @@
-This folder contains some side projects based on Gravity.
-
-## Butterfly
-Butterfly is a MacOS application that demonstrate how to use Gravity parser callback to efficiently implement syntax highlighting.
-It also includes basic code completion capabilities that will be expanded in the near future.
-
-<p align="center">
-<img src="https://github.com/marcobambini/gravity/blob/master/projects/Butterfly/screenshot.png?raw=true" alt="Butterfly Screenshot" width="554px" height="443px">
-</p>
-
-The ultimate goal for the Butterfly project is to become a fully featured IDE for the Gravity language.

+ 2 - 0
src/cli/gravity.c

@@ -7,6 +7,7 @@
 //
 //
 
 
 #include "gravity_compiler.h"
 #include "gravity_compiler.h"
+#include "gravity_optionals.h"
 #include "gravity_utils.h"
 #include "gravity_utils.h"
 #include "gravity_core.h"
 #include "gravity_core.h"
 #include "gravity_vm.h"
 #include "gravity_vm.h"
@@ -262,6 +263,7 @@ cleanup:
 	if (compiler) gravity_compiler_free(compiler);
 	if (compiler) gravity_compiler_free(compiler);
 	if (vm) gravity_vm_free(vm);
 	if (vm) gravity_vm_free(vm);
 	gravity_core_free();
 	gravity_core_free();
+    gravity_optionals_free();
 	
 	
 	#if GRAVITY_MEMORY_DEBUG
 	#if GRAVITY_MEMORY_DEBUG
 	size_t current_memory = mem_leaks();
 	size_t current_memory = mem_leaks();

+ 1 - 0
src/compiler/gravity_codegen.c

@@ -373,6 +373,7 @@ static void visit_flow_if_stmt (gvisitor_t *self, gnode_flow_stmt_t *node) {
 
 
 static void visit_flow_switch_stmt (gvisitor_t *self, gnode_flow_stmt_t *node) {
 static void visit_flow_switch_stmt (gvisitor_t *self, gnode_flow_stmt_t *node) {
 	DEBUG_CODEGEN("visit_flow_switch_stmt");
 	DEBUG_CODEGEN("visit_flow_switch_stmt");
+    return;
 	
 	
 	visit(node->cond);
 	visit(node->cond);
 	visit(node->stmt);
 	visit(node->stmt);

+ 4 - 1
src/compiler/gravity_compiler.c

@@ -96,7 +96,10 @@ static void gravity_compiler_reset (gravity_compiler_t *compiler, bool free_core
 	}
 	}
 	
 	
 	// feel free to free core if someone requires it
 	// feel free to free core if someone requires it
-	if (free_core) gravity_core_free();
+    if (free_core) {
+        gravity_core_free();
+        gravity_optionals_free();
+    }
 	
 	
 	// reset internal pointers
 	// reset internal pointers
 	compiler->vm = NULL;
 	compiler->vm = NULL;

+ 17 - 1
src/compiler/gravity_parser.c

@@ -7,6 +7,7 @@
 //
 //
 
 
 #include "gravity_symboltable.h"
 #include "gravity_symboltable.h"
+#include "gravity_optionals.h"
 #include "gravity_parser.h"
 #include "gravity_parser.h"
 #include "gravity_macros.h"
 #include "gravity_macros.h"
 #include "gravity_lexer.h"
 #include "gravity_lexer.h"
@@ -2505,11 +2506,26 @@ static void parser_register_core_classes (gravity_parser_t *parser) {
 	gnode_array_push(parser->statements, (gnode_t *)node);
 	gnode_array_push(parser->statements, (gnode_t *)node);
 }
 }
 
 
+static void parser_register_optional_classes (gravity_parser_t *parser) {
+    // for each optional identifier create a dummy extern variable node
+    gnode_r	*decls = gnode_array_create();
+    
+    #ifdef GRAVITY_INCLUDE_MATH
+    gnode_t *decl = gnode_variable_create(NO_TOKEN, string_dup(GRAVITY_MATH_NAME()), NULL, 0, NULL, LAST_DECLARATION());
+    gnode_array_push(decls, decl);
+    #endif
+    
+    // register a variable declaration node in global statements
+    gnode_t *node = gnode_variable_decl_create(NO_TOKEN, TOK_KEY_VAR, 0, TOK_KEY_EXTERN, decls, NULL, LAST_DECLARATION());;
+    gnode_array_push(parser->statements, (gnode_t *)node);
+}
+
 static uint32_t parser_run (gravity_parser_t *parser) {
 static uint32_t parser_run (gravity_parser_t *parser) {
 	DEBUG_PARSER("=== BEGIN PARSING ===");
 	DEBUG_PARSER("=== BEGIN PARSING ===");
 	
 	
-	// register core classes as extern globals
+	// register core and optional classes as extern globals
 	parser_register_core_classes(parser);
 	parser_register_core_classes(parser);
+    parser_register_optional_classes(parser);
 	
 	
 	nanotime_t t1 = nanotime();
 	nanotime_t t1 = nanotime();
 	do {
 	do {

+ 0 - 0
src/optional/README.md → src/optionals/README.md


+ 616 - 0
src/optionals/gravity_math.c

@@ -0,0 +1,616 @@
+//
+//  gravity_math.c
+//  gravity
+//
+//  Created by Marco Bambini on 14/08/2017.
+//  Copyright © 2017 CreoLabs. All rights reserved.
+//
+//  Based on: https://www.w3schools.com/jsref/jsref_obj_math.asp
+
+#include <math.h>
+#include <time.h>
+#include <inttypes.h>
+#include "gravity_vm.h"
+#include "gravity_math.h"
+#include "gravity_core.h"
+#include "gravity_hash.h"
+#include "gravity_macros.h"
+#include "gravity_vmmacros.h"
+
+#define MATH_CLASS_NAME             "Math"
+
+#ifdef GRAVITY_ENABLE_DOUBLE
+#define SIN                         sin
+#define COS                         cos
+#define TAN                         tan
+#define ASIN                        asin
+#define ACOS                        acos
+#define ATAN                        atan
+#define ATAN2                       atan2
+#define CEIL                        ceil
+#define FLOOR                       floor
+#define ROUND                       round
+#define LOG                         log
+#define POW                         pow
+#define EXP                         exp
+#define SQRT                        sqrt
+#else
+#define SIN                         sinf
+#define COS                         cosf
+#define TAN                         tanf
+#define ASIN                        asinf
+#define ACOS                        acosf
+#define ATAN                        atanf
+#define ATAN2                       atan2
+#define CEIL                        ceilf
+#define FLOOR                       floorf
+#define ROUND                       roundf
+#define LOG                         logf
+#define POW                         powf
+#define EXP                         expf
+#define SQRT                        sqrtf
+#endif
+
+static gravity_class_t              *gravity_class_math = NULL;
+static uint32_t                     refcount = 0;
+
+// MARK: - Implementation -
+
+// returns the absolute value of x
+static bool math_abs (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t value = GET_VALUE(0);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_int_t computed_value;
+        #ifdef GRAVITY_ENABLE_INT64
+        computed_value = (gravity_int_t)llabs((long long)value.n);
+        #else
+        computed_value = (gravity_int_t)labs((long)value.n);
+        #endif
+        RETURN_VALUE(VALUE_FROM_INT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value;
+        #ifdef GRAVITY_ENABLE_DOUBLE
+        computed_value = (gravity_float_t)fabs((double)value.f);
+        #else
+        computed_value = (gravity_float_t)fabsf((float)value.f);
+        #endif
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns the arccosine of x, in radians
+static bool math_acos (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t value = GET_VALUE(0);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)ACOS((gravity_float_t)value.n);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)ACOS((gravity_float_t)value.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns the arcsine of x, in radians
+static bool math_asin (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t value = GET_VALUE(0);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)ASIN((gravity_float_t)value.n);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)ASIN((gravity_float_t)value.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns the arctangent of x as a numeric value between -PI/2 and PI/2 radians
+static bool math_atan (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t value = GET_VALUE(0);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)ATAN((gravity_float_t)value.n);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)ATAN((gravity_float_t)value.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns the arctangent of the quotient of its arguments
+static bool math_atan2 (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm)
+    
+    if (nargs != 2) RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+    
+    gravity_value_t value = GET_VALUE(0);
+    gravity_value_t value2 = GET_VALUE(1);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    gravity_float_t n2;
+    if (VALUE_ISA_INT(value2)) n2 = (gravity_float_t)value2.n;
+    else if (VALUE_ISA_FLOAT(value2)) n2 = (gravity_float_t)value2.f;
+    else RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)ATAN2((gravity_float_t)value.n, n2);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)ATAN2((gravity_float_t)value.f, n2);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns x, rounded upwards to the nearest integer
+static bool math_ceil (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t value = GET_VALUE(0);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)CEIL((gravity_float_t)value.n);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)CEIL((gravity_float_t)value.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns the cosine of x (x is in radians)
+static bool math_cos (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t value = GET_VALUE(0);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)COS((gravity_float_t)value.n);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)COS((gravity_float_t)value.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns the value of Ex
+static bool math_exp (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t value = GET_VALUE(0);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)EXP((gravity_float_t)value.n);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)EXP((gravity_float_t)value.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns x, rounded downwards to the nearest integer
+static bool math_floor (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t value = GET_VALUE(0);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)FLOOR((gravity_float_t)value.n);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)FLOOR((gravity_float_t)value.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns the natural logarithm (base E) of x
+static bool math_log (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t value = GET_VALUE(0);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)LOG((gravity_float_t)value.n);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)LOG((gravity_float_t)value.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns the number with the highest value
+static bool math_max (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    gravity_float_t n = FLOAT_MIN;
+    gravity_value_t result = VALUE_FROM_UNDEFINED;
+    
+    for (uint16_t i = 0; i<nargs; ++i) {
+        gravity_value_t value = GET_VALUE(i);
+        if (VALUE_ISA_INT(value)) {
+            if ((gravity_float_t)value.n > n) result = value;
+        } else if (VALUE_ISA_FLOAT(value)) {
+            if (value.f > n) result = value;
+        } else continue;
+    }
+    
+    RETURN_VALUE(result, rindex);
+}
+
+// returns the number with the lowest value
+static bool math_min (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    gravity_float_t n = FLOAT_MAX;
+    gravity_value_t result = VALUE_FROM_UNDEFINED;
+    
+    for (uint16_t i = 0; i<nargs; ++i) {
+        gravity_value_t value = GET_VALUE(i);
+        if (VALUE_ISA_INT(value)) {
+            if ((gravity_float_t)value.n < n) result = value;
+        } else if (VALUE_ISA_FLOAT(value)) {
+            if (value.f < n) result = value;
+        } else continue;
+    }
+    
+    RETURN_VALUE(result, rindex);
+}
+
+// returns the value of x to the power of y
+static bool math_pow (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm)
+    
+    if (nargs != 2) RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+    
+    gravity_value_t value = GET_VALUE(0);
+    gravity_value_t value2 = GET_VALUE(1);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    gravity_float_t n2;
+    if (VALUE_ISA_INT(value2)) n2 = (gravity_float_t)value2.n;
+    else if (VALUE_ISA_FLOAT(value2)) n2 = (gravity_float_t)value2.f;
+    else RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)POW((gravity_float_t)value.n, n2);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)POW((gravity_float_t)value.f, n2);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns a random number between 0 and 1
+static bool math_random (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, args, nargs)
+    
+    // only seed once
+    static bool already_seeded = false;
+    if (!already_seeded) {
+        srand((unsigned)time(NULL));
+        already_seeded = true;
+    }
+    
+    int r = rand();
+    RETURN_VALUE(VALUE_FROM_FLOAT(r / RAND_MAX), rindex);
+}
+
+// rounds x to the nearest integer
+static bool math_round (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t value = GET_VALUE(0);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)ROUND((gravity_float_t)value.n);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)ROUND((gravity_float_t)value.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns the sine of x (x is in radians)
+static bool math_sin (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t value = GET_VALUE(0);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)SIN((gravity_float_t)value.n);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)SIN((gravity_float_t)value.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns the square root of x
+static bool math_sqrt (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t value = GET_VALUE(0);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)SQRT((gravity_float_t)value.n);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)SQRT((gravity_float_t)value.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// returns the tangent of an angle
+static bool math_tan (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, nargs)
+    gravity_value_t value = GET_VALUE(0);
+    
+    if (VALUE_ISA_NULL(value)) {
+        RETURN_VALUE(VALUE_FROM_INT(0), rindex);
+    }
+    
+    if (VALUE_ISA_INT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)TAN((gravity_float_t)value.n);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    if (VALUE_ISA_FLOAT(value)) {
+        gravity_float_t computed_value = (gravity_float_t)TAN((gravity_float_t)value.f);
+        RETURN_VALUE(VALUE_FROM_FLOAT(computed_value), rindex);
+    }
+    
+    // should be NaN
+    RETURN_VALUE(VALUE_FROM_UNDEFINED, rindex);
+}
+
+// CONSTANTS
+static bool math_PI (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, args, nargs)
+    RETURN_VALUE(VALUE_FROM_FLOAT(3.141592653589793), rindex);
+}
+
+static bool math_E (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, args, nargs)
+    RETURN_VALUE(VALUE_FROM_FLOAT(2.718281828459045), rindex);
+}
+
+static bool math_LN2 (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, args, nargs)
+    RETURN_VALUE(VALUE_FROM_FLOAT(0.6931471805599453), rindex);
+}
+
+static bool math_LN10 (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, args, nargs)
+    RETURN_VALUE(VALUE_FROM_FLOAT(2.302585092994046), rindex);
+}
+
+static bool math_LOG2E (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, args, nargs)
+    RETURN_VALUE(VALUE_FROM_FLOAT(1.4426950408889634), rindex);
+}
+
+static bool math_LOG10E (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, args, nargs)
+    RETURN_VALUE(VALUE_FROM_FLOAT(0.4342944819032518), rindex);
+}
+
+static bool math_SQRT2 (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, args, nargs)
+    RETURN_VALUE(VALUE_FROM_FLOAT(1.4142135623730951), rindex);
+}
+
+static bool math_SQRT1_2 (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, uint32_t rindex) {
+    #pragma unused(vm, args, nargs)
+    RETURN_VALUE(VALUE_FROM_FLOAT(0.7071067811865476), rindex);
+}
+
+// MARK: - Internals -
+
+//static void free_computed_property (gravity_class_t *c, const char *name) {
+//    // computed properties are not registered inside VM gc so they need to be manually freed here
+//    STATICVALUE_FROM_STRING(key, name, strlen(name));
+//    gravity_closure_t *closure = gravity_class_lookup_closure(c, key);
+//    computed_property_free(closure);
+//    gravity_hash_remove(c->htable, key);
+//}
+
+static void create_optional_class (void) {
+    gravity_class_math = gravity_class_new_pair(NULL, MATH_CLASS_NAME, NULL, 0, 0);
+    gravity_class_t *meta = gravity_class_get_meta(gravity_class_math);
+    
+    gravity_class_bind(meta, "abs", NEW_CLOSURE_VALUE(math_abs));
+    gravity_class_bind(meta, "acos", NEW_CLOSURE_VALUE(math_acos));
+    gravity_class_bind(meta, "asin", NEW_CLOSURE_VALUE(math_asin));
+    gravity_class_bind(meta, "atan", NEW_CLOSURE_VALUE(math_atan));
+    gravity_class_bind(meta, "atan2", NEW_CLOSURE_VALUE(math_atan2));
+    gravity_class_bind(meta, "ceil", NEW_CLOSURE_VALUE(math_ceil));
+    gravity_class_bind(meta, "cos", NEW_CLOSURE_VALUE(math_cos));
+    gravity_class_bind(meta, "exp", NEW_CLOSURE_VALUE(math_exp));
+    gravity_class_bind(meta, "floor", NEW_CLOSURE_VALUE(math_floor));
+    gravity_class_bind(meta, "log", NEW_CLOSURE_VALUE(math_log));
+    gravity_class_bind(meta, "max", NEW_CLOSURE_VALUE(math_max));
+    gravity_class_bind(meta, "min", NEW_CLOSURE_VALUE(math_min));
+    gravity_class_bind(meta, "pow", NEW_CLOSURE_VALUE(math_pow));
+    gravity_class_bind(meta, "random", NEW_CLOSURE_VALUE(math_random));
+    gravity_class_bind(meta, "round", NEW_CLOSURE_VALUE(math_round));
+    gravity_class_bind(meta, "sin", NEW_CLOSURE_VALUE(math_sin));
+    gravity_class_bind(meta, "sqrt", NEW_CLOSURE_VALUE(math_sqrt));
+    gravity_class_bind(meta, "tan", NEW_CLOSURE_VALUE(math_tan));
+    
+    gravity_closure_t *closure = NULL;
+    closure = computed_property_create(NULL, NEW_FUNCTION(math_PI), NULL);
+    gravity_class_bind(meta, "PI", VALUE_FROM_OBJECT(closure));
+    closure = computed_property_create(NULL, NEW_FUNCTION(math_E), NULL);
+    gravity_class_bind(meta, "E", VALUE_FROM_OBJECT(closure));
+    closure = computed_property_create(NULL, NEW_FUNCTION(math_LN2), NULL);
+    gravity_class_bind(meta, "LN2", VALUE_FROM_OBJECT(closure));
+    closure = computed_property_create(NULL, NEW_FUNCTION(math_LN10), NULL);
+    gravity_class_bind(meta, "LN10", VALUE_FROM_OBJECT(closure));
+    closure = computed_property_create(NULL, NEW_FUNCTION(math_LOG2E), NULL);
+    gravity_class_bind(meta, "LOG2E", VALUE_FROM_OBJECT(closure));
+    closure = computed_property_create(NULL, NEW_FUNCTION(math_LOG10E), NULL);
+    gravity_class_bind(meta, "LOG10E", VALUE_FROM_OBJECT(closure));
+    closure = computed_property_create(NULL, NEW_FUNCTION(math_SQRT2), NULL);
+    gravity_class_bind(meta, "SQRT2", VALUE_FROM_OBJECT(closure));
+    closure = computed_property_create(NULL, NEW_FUNCTION(math_SQRT1_2), NULL);
+    gravity_class_bind(meta, "SQRT1_2", VALUE_FROM_OBJECT(closure));
+    
+    SETMETA_INITED(gravity_class_math);
+}
+
+// MARK: - Commons -
+
+bool gravity_ismath_class (gravity_class_t *c) {
+    return (c == gravity_class_math);
+}
+
+const char *gravity_math_name (void) {
+    return MATH_CLASS_NAME;
+}
+
+void gravity_math_register (gravity_vm *vm) {
+    if (!gravity_class_math) create_optional_class();
+    ++refcount;
+    
+    if (gravity_vm_ismini(vm)) return;
+    gravity_vm_setvalue(vm, MATH_CLASS_NAME, VALUE_FROM_OBJECT(gravity_class_math));
+}
+
+void gravity_math_free (void) {
+    if (!gravity_class_math) return;
+    
+    --refcount;
+    if (refcount) return;
+    
+    mem_check(false);
+    gravity_class_t *meta = gravity_class_get_meta(gravity_class_math);
+    computed_property_free(meta, "PI", true);
+    computed_property_free(meta, "E", true);
+    computed_property_free(meta, "LN2", true);
+    computed_property_free(meta, "LN10", true);
+    computed_property_free(meta, "LOG2E", true);
+    computed_property_free(meta, "LOG10E", true);
+    computed_property_free(meta, "SQRT2", true);
+    computed_property_free(meta, "SQRT1_2", true);
+    gravity_class_free_core(NULL, meta);
+    gravity_class_free_core(NULL, gravity_class_math);
+    mem_check(true);
+    
+    gravity_class_math = NULL;
+}
+

+ 19 - 0
src/optionals/gravity_math.h

@@ -0,0 +1,19 @@
+//
+//  gravity_math.h
+//  gravity
+//
+//  Created by Marco Bambini on 14/08/2017.
+//  Copyright © 2017 CreoLabs. All rights reserved.
+//
+
+#ifndef __GRAVITY_MATH__
+#define __GRAVITY_MATH__
+
+#include "gravity_value.h"
+
+void gravity_math_register (gravity_vm *vm);
+void gravity_math_free (void);
+bool gravity_ismath_class (gravity_class_t *c);
+const char *gravity_math_name (void);
+
+#endif

+ 29 - 0
src/optionals/gravity_optionals.h

@@ -0,0 +1,29 @@
+//
+//  gravity_optionals.h
+//  gravity
+//
+//  Created by Marco Bambini on 14/08/2017.
+//  Copyright © 2017 CreoLabs. All rights reserved.
+//
+
+#ifndef __GRAVITY_OPTIONALS__
+#define __GRAVITY_OPTIONALS__
+
+#ifndef GRAVITY_INCLUDE_MATH
+#define GRAVITY_INCLUDE_MATH
+#endif
+
+#ifdef GRAVITY_INCLUDE_MATH
+#define GRAVITY_MATH_REGISTER(_vm)          gravity_math_register(_vm)
+#define GRAVITY_MATH_FREE()                 gravity_math_free()
+#define GRAVITY_MATH_NAME()                 gravity_math_name()
+#define GRAVITY_ISMATH_CLASS(_c)            gravity_ismath_class(_c)
+#include "gravity_math.h"
+#else
+#define GRAVITY_MATH_REGISTER(_vm)
+#define GRAVITY_MATH_FREE()
+#define GRAVITY_MATH_NAME()                 NULL
+#define GRAVITY_ISMATH_CLASS(_c)            false
+#endif
+
+#endif

+ 16 - 62
src/runtime/gravity_core.c

@@ -17,6 +17,7 @@
 #include "gravity_opcodes.h"
 #include "gravity_opcodes.h"
 #include "gravity_macros.h"
 #include "gravity_macros.h"
 #include "gravity_memory.h"
 #include "gravity_memory.h"
+#include "gravity_vmmacros.h"
 
 
 // Gravity base classes (the isa pointer in each object).
 // Gravity base classes (the isa pointer in each object).
 // Null and Undefined points to same class (Null) and they
 // Null and Undefined points to same class (Null) and they
@@ -88,40 +89,6 @@ gravity_class_t *gravity_class_range;
 gravity_class_t *gravity_class_upvalue;
 gravity_class_t *gravity_class_upvalue;
 gravity_class_t *gravity_class_system;
 gravity_class_t *gravity_class_system;
 
 
-#define SETMETA_INITED(c)						gravity_class_get_meta(c)->is_inited = true
-#define GET_VALUE(_idx)							args[_idx]
-#define RETURN_VALUE(_v,_i)						do {gravity_vm_setslot(vm, _v, _i); return true;} while(0)
-#define RETURN_CLOSURE(_v,_i)					do {gravity_vm_setslot(vm, _v, _i); return false;} while(0)
-#define RETURN_FIBER()							return false
-#define RETURN_NOVALUE()						return true
-#define RETURN_ERROR(...)						do {																		\
-													char buffer[4096];														\
-													snprintf(buffer, sizeof(buffer), __VA_ARGS__);							\
-													gravity_fiber_seterror(gravity_vm_fiber(vm), (const char *) buffer);	\
-													gravity_vm_setslot(vm, VALUE_FROM_NULL, rindex);						\
-													return false;															\
-												} while(0)
-
-#define DECLARE_1VARIABLE(_v,_idx)				register gravity_value_t _v = GET_VALUE(_idx)
-#define DECLARE_2VARIABLES(_v1,_v2,_idx1,_idx2) DECLARE_1VARIABLE(_v1,_idx1);DECLARE_1VARIABLE(_v2,_idx2)
-
-#define CHECK_VALID(_v, _msg)					if (VALUE_ISA_NOTVALID(_v)) RETURN_ERROR(_msg)
-#define INTERNAL_CONVERT_FLOAT(_v)				_v = convert_value2float(vm,_v); CHECK_VALID(_v, "Unable to convert object to Float")
-#define INTERNAL_CONVERT_BOOL(_v)				_v = convert_value2bool(vm,_v); CHECK_VALID(_v, "Unable to convert object to Bool")
-#define INTERNAL_CONVERT_INT(_v)				_v = convert_value2int(vm,_v); CHECK_VALID(_v, "Unable to convert object to Int")
-#define INTERNAL_CONVERT_STRING(_v)				_v = convert_value2string(vm,_v); CHECK_VALID(_v, "Unable to convert object to String")
-
-#define NEW_FUNCTION(_fptr)						(gravity_function_new_internal(NULL, NULL, _fptr, 0))
-#define NEW_CLOSURE_VALUE(_fptr)				((gravity_value_t){	.isa = gravity_class_closure,		\
-																	.p = (gravity_object_t *)gravity_closure_new(NULL, NEW_FUNCTION(_fptr))})
-
-#define FUNCTION_ISA_SPECIAL(_f)				(OBJECT_ISA_FUNCTION(_f) && (_f->tag == EXEC_TYPE_SPECIAL))
-#define FUNCTION_ISA_DEFAULT_GETTER(_f)			((_f->index < GRAVITY_COMPUTED_INDEX) && (_f->special[EXEC_TYPE_SPECIAL_GETTER] == NULL))
-#define FUNCTION_ISA_DEFAULT_SETTER(_f)			((_f->index < GRAVITY_COMPUTED_INDEX) && (_f->special[EXEC_TYPE_SPECIAL_SETTER] == NULL))
-#define FUNCTION_ISA_GETTER(_f)					(_f->special[EXEC_TYPE_SPECIAL_GETTER] != NULL)
-#define FUNCTION_ISA_SETTER(_f)					(_f->special[EXEC_TYPE_SPECIAL_SETTER] != NULL)
-#define FUNCTION_ISA_BRIDGED(_f)				(_f->index == GRAVITY_BRIDGE_INDEX)
-
 // MARK: - Utils -
 // MARK: - Utils -
 static void map_keys_array (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data) {
 static void map_keys_array (gravity_hash_t *hashtable, gravity_value_t key, gravity_value_t value, void *data) {
     #pragma unused (hashtable, value)
     #pragma unused (hashtable, value)
@@ -2287,14 +2254,18 @@ static bool system_exit (gravity_vm *vm, gravity_value_t *args, uint16_t nargs,
 
 
 // MARK: - CORE -
 // MARK: - CORE -
 
 
-static gravity_closure_t *computed_property_create (gravity_vm *vm, gravity_function_t *getter_func, gravity_function_t *setter_func) {
+gravity_closure_t *computed_property_create (gravity_vm *vm, gravity_function_t *getter_func, gravity_function_t *setter_func) {
 	gravity_closure_t *getter_closure = (getter_func) ? gravity_closure_new(vm, getter_func) : NULL;
 	gravity_closure_t *getter_closure = (getter_func) ? gravity_closure_new(vm, getter_func) : NULL;
 	gravity_closure_t *setter_closure = (setter_func) ? gravity_closure_new(vm, setter_func) : NULL;
 	gravity_closure_t *setter_closure = (setter_func) ? gravity_closure_new(vm, setter_func) : NULL;
 	gravity_function_t *f = gravity_function_new_special(vm, NULL, GRAVITY_COMPUTED_INDEX, getter_closure, setter_closure);
 	gravity_function_t *f = gravity_function_new_special(vm, NULL, GRAVITY_COMPUTED_INDEX, getter_closure, setter_closure);
 	return gravity_closure_new(vm, f);
 	return gravity_closure_new(vm, f);
 }
 }
 
 
-static void computed_property_free (gravity_closure_t *closure) {
+void computed_property_free (gravity_class_t *c, const char *name, bool remove_flag) {
+    STATICVALUE_FROM_STRING(key, name, strlen(name));
+    gravity_closure_t *closure = gravity_class_lookup_closure(c, key);
+    assert(closure);
+    
     gravity_closure_t *getter = (gravity_closure_t *)closure->f->special[0];
     gravity_closure_t *getter = (gravity_closure_t *)closure->f->special[0];
     gravity_closure_t *setter = (closure->f->special[0] != closure->f->special[1]) ? (gravity_closure_t *)closure->f->special[1] : NULL;
     gravity_closure_t *setter = (closure->f->special[0] != closure->f->special[1]) ? (gravity_closure_t *)closure->f->special[1] : NULL;
     if (getter) {
     if (getter) {
@@ -2310,6 +2281,8 @@ static void computed_property_free (gravity_closure_t *closure) {
     
     
     if (closure->f) gravity_function_free(NULL, closure->f);
     if (closure->f) gravity_function_free(NULL, closure->f);
     gravity_closure_free(NULL, closure);
     gravity_closure_free(NULL, closure);
+    
+    if (remove_flag) gravity_hash_remove(c->htable, key);
 }
 }
 
 
 static void gravity_core_init (void) {
 static void gravity_core_init (void) {
@@ -2615,32 +2588,14 @@ void gravity_core_free (void) {
 	// this function should never be called
 	// this function should never be called
 	// it is just called when we need to internally check for memory leaks
 	// it is just called when we need to internally check for memory leaks
 	
 	
-	mem_check(false);
     // computed properties are not registered inside VM gc so they need to be manually freed here
     // computed properties are not registered inside VM gc so they need to be manually freed here
-    {
-        STATICVALUE_FROM_STRING(key, "count", strlen("count"));
-        gravity_closure_t *list_count = gravity_class_lookup_closure(gravity_class_list, key);
-        computed_property_free(list_count);
-        gravity_hash_remove(gravity_class_list->htable, key);
-        gravity_closure_t *map_count = gravity_class_lookup_closure(gravity_class_map, key);
-        computed_property_free(map_count);
-        gravity_hash_remove(gravity_class_map->htable, key);
-        gravity_closure_t *range_count = gravity_class_lookup_closure(gravity_class_range, key);
-        computed_property_free(range_count);
-        gravity_hash_remove(gravity_class_range->htable, key);
-    }
-    {
-        STATICVALUE_FROM_STRING(key, "length", strlen("length"));
-        gravity_closure_t *string_length = gravity_class_lookup_closure(gravity_class_string, key);
-        computed_property_free(string_length);
-        gravity_hash_remove(gravity_class_string->htable, key);
-    }
-    {
-        STATICVALUE_FROM_STRING(key, "gcenabled", strlen("gcenabled"));
-        gravity_closure_t *system_gcenabled = gravity_class_lookup_closure(gravity_class_get_meta(gravity_class_system), key);
-        computed_property_free(system_gcenabled);
-        gravity_hash_remove(gravity_class_get_meta(gravity_class_system)->htable, key);
-    }
+	mem_check(false);
+    computed_property_free(gravity_class_list, "count", true);
+    computed_property_free(gravity_class_map, "count", true);
+    computed_property_free(gravity_class_range, "count", true);
+    computed_property_free(gravity_class_string, "length", true);
+    gravity_class_t *system_meta = gravity_class_get_meta(gravity_class_system);
+    computed_property_free(system_meta, "gcenabled", true);
         
         
 	gravity_class_free_core(NULL, gravity_class_get_meta(gravity_class_int));
 	gravity_class_free_core(NULL, gravity_class_get_meta(gravity_class_int));
 	gravity_class_free_core(NULL, gravity_class_int);
 	gravity_class_free_core(NULL, gravity_class_int);
@@ -2670,7 +2625,6 @@ void gravity_core_free (void) {
 	gravity_class_free_core(NULL, gravity_class_upvalue);
 	gravity_class_free_core(NULL, gravity_class_upvalue);
 	
 	
 	// before freeing the meta class we need to remove entries with duplicated functions
 	// before freeing the meta class we need to remove entries with duplicated functions
-	gravity_class_t *system_meta = gravity_class_get_meta(gravity_class_system);
 	{STATICVALUE_FROM_STRING(key, "gcminthreshold", strlen("gcminthreshold")); gravity_hash_remove(system_meta->htable, key);}
 	{STATICVALUE_FROM_STRING(key, "gcminthreshold", strlen("gcminthreshold")); gravity_hash_remove(system_meta->htable, key);}
 	{STATICVALUE_FROM_STRING(key, "gcthreshold", strlen("gcthreshold")); gravity_hash_remove(system_meta->htable, key);}
 	{STATICVALUE_FROM_STRING(key, "gcthreshold", strlen("gcthreshold")); gravity_hash_remove(system_meta->htable, key);}
 	{STATICVALUE_FROM_STRING(key, "gcratio", strlen("gcratio")); gravity_hash_remove(system_meta->htable, key);}
 	{STATICVALUE_FROM_STRING(key, "gcratio", strlen("gcratio")); gravity_hash_remove(system_meta->htable, key);}

+ 4 - 0
src/runtime/gravity_core.h

@@ -28,6 +28,10 @@ gravity_value_t convert_value2float (gravity_vm *vm, gravity_value_t v);
 gravity_value_t convert_value2bool (gravity_vm *vm, gravity_value_t v);
 gravity_value_t convert_value2bool (gravity_vm *vm, gravity_value_t v);
 gravity_value_t convert_value2string (gravity_vm *vm, gravity_value_t v);
 gravity_value_t convert_value2string (gravity_vm *vm, gravity_value_t v);
 
 
+// internal functions
+gravity_closure_t *computed_property_create (gravity_vm *vm, gravity_function_t *getter_func, gravity_function_t *setter_func);
+void              computed_property_free (gravity_class_t *c, const char *name, bool remove_flag);
+    
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
 #endif
 #endif

+ 16 - 0
src/runtime/gravity_vm.c

@@ -16,6 +16,7 @@
 #include "gravity_memory.h"
 #include "gravity_memory.h"
 #include "gravity_vmmacros.h"
 #include "gravity_vmmacros.h"
 #include "gravity_json.h"
 #include "gravity_json.h"
+#include "gravity_optionals.h"
 
 
 // MARK: Internals -
 // MARK: Internals -
 static void gravity_gc_cleanup (gravity_vm *vm);
 static void gravity_gc_cleanup (gravity_vm *vm);
@@ -292,6 +293,20 @@ static void gravity_vm_loadclass (gravity_vm *vm, gravity_class_t *c) {
 	gravity_hash_transform(meta->htable, gravity_gc_transform, (void *)vm);
 	gravity_hash_transform(meta->htable, gravity_gc_transform, (void *)vm);
 }
 }
 
 
+// MARK: Internals -
+
+static void gravity_optionals_register (gravity_vm *vm) {
+    GRAVITY_MATH_REGISTER(vm);
+}
+
+void gravity_optionals_free() {
+    GRAVITY_MATH_FREE();
+}
+
+bool gravity_isoptional_class (gravity_class_t *c) {
+    return GRAVITY_ISMATH_CLASS(c);
+}
+
 // MARK: -
 // MARK: -
 
 
 static bool gravity_vm_exec (gravity_vm *vm) {
 static bool gravity_vm_exec (gravity_vm *vm) {
@@ -1316,6 +1331,7 @@ gravity_vm *gravity_vm_new (gravity_delegate_t *delegate/*, uint32_t context_siz
 	
 	
 	// init base and core
 	// init base and core
 	gravity_core_register(vm);
 	gravity_core_register(vm);
+    gravity_optionals_register(vm);
 	gravity_cache_setup();
 	gravity_cache_setup();
 	
 	
 	RESET_STATS(vm);
 	RESET_STATS(vm);

+ 3 - 0
src/runtime/gravity_vm.h

@@ -71,6 +71,9 @@ GRAVITY_API gravity_value_t		gravity_vm_get (gravity_vm *vm, const char *key);
 GRAVITY_API bool				gravity_vm_set (gravity_vm *vm, const char *key, gravity_value_t value);
 GRAVITY_API bool				gravity_vm_set (gravity_vm *vm, const char *key, gravity_value_t value);
 GRAVITY_API char				*gravity_vm_anonymous (gravity_vm *vm);
 GRAVITY_API char				*gravity_vm_anonymous (gravity_vm *vm);
 
 
+GRAVITY_API bool                gravity_isoptional_class (gravity_class_t *c);
+GRAVITY_API void                gravity_optionals_free (void);
+
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
 #endif
 #endif

+ 36 - 0
src/runtime/gravity_vmmacros.h

@@ -9,6 +9,8 @@
 #ifndef __GRAVITY_VMMACROS__
 #ifndef __GRAVITY_VMMACROS__
 #define __GRAVITY_VMMACROS__
 #define __GRAVITY_VMMACROS__
 
 
+// MACROS used in VM
+
 #if 0
 #if 0
 #define DEBUG_CALL(s, f)								printf("%s %s\n", s, f->identifier)
 #define DEBUG_CALL(s, f)								printf("%s %s\n", s, f->identifier)
 #else
 #else
@@ -264,4 +266,38 @@
 													LOAD_FRAME();																			\
 													LOAD_FRAME();																			\
 													SYNC_STACKTOP(_c, MAXNUM(_rneed, rwin))
 													SYNC_STACKTOP(_c, MAXNUM(_rneed, rwin))
 
 
+// MACROS used in core and optionals
+#define SETMETA_INITED(c)                           gravity_class_get_meta(c)->is_inited = true
+#define GET_VALUE(_idx)                             args[_idx]
+#define RETURN_VALUE(_v,_i)                         do {gravity_vm_setslot(vm, _v, _i); return true;} while(0)
+#define RETURN_CLOSURE(_v,_i)                       do {gravity_vm_setslot(vm, _v, _i); return false;} while(0)
+#define RETURN_FIBER()                              return false
+#define RETURN_NOVALUE()                            return true
+#define RETURN_ERROR(...)                           do {                                                                                    \
+                                                        char buffer[4096];                                                                  \
+                                                        snprintf(buffer, sizeof(buffer), __VA_ARGS__);                                      \
+                                                        gravity_fiber_seterror(gravity_vm_fiber(vm), (const char *) buffer);                \
+                                                        gravity_vm_setslot(vm, VALUE_FROM_NULL, rindex);                                    \
+                                                        return false;                                                                       \
+                                                    } while(0)
+
+#define DECLARE_1VARIABLE(_v,_idx)                  register gravity_value_t _v = GET_VALUE(_idx)
+#define DECLARE_2VARIABLES(_v1,_v2,_idx1,_idx2)     DECLARE_1VARIABLE(_v1,_idx1);DECLARE_1VARIABLE(_v2,_idx2)
+
+#define CHECK_VALID(_v, _msg)                       if (VALUE_ISA_NOTVALID(_v)) RETURN_ERROR(_msg)
+#define INTERNAL_CONVERT_FLOAT(_v)                  _v = convert_value2float(vm,_v); CHECK_VALID(_v, "Unable to convert object to Float")
+#define INTERNAL_CONVERT_BOOL(_v)                   _v = convert_value2bool(vm,_v); CHECK_VALID(_v, "Unable to convert object to Bool")
+#define INTERNAL_CONVERT_INT(_v)                    _v = convert_value2int(vm,_v); CHECK_VALID(_v, "Unable to convert object to Int")
+#define INTERNAL_CONVERT_STRING(_v)                 _v = convert_value2string(vm,_v); CHECK_VALID(_v, "Unable to convert object to String")
+
+#define NEW_FUNCTION(_fptr)                         (gravity_function_new_internal(NULL, NULL, _fptr, 0))
+#define NEW_CLOSURE_VALUE(_fptr)                    ((gravity_value_t){.isa = gravity_class_closure,.p = (gravity_object_t *)gravity_closure_new(NULL, NEW_FUNCTION(_fptr))})
+
+#define FUNCTION_ISA_SPECIAL(_f)                    (OBJECT_ISA_FUNCTION(_f) && (_f->tag == EXEC_TYPE_SPECIAL))
+#define FUNCTION_ISA_DEFAULT_GETTER(_f)             ((_f->index < GRAVITY_COMPUTED_INDEX) && (_f->special[EXEC_TYPE_SPECIAL_GETTER] == NULL))
+#define FUNCTION_ISA_DEFAULT_SETTER(_f)             ((_f->index < GRAVITY_COMPUTED_INDEX) && (_f->special[EXEC_TYPE_SPECIAL_SETTER] == NULL))
+#define FUNCTION_ISA_GETTER(_f)                     (_f->special[EXEC_TYPE_SPECIAL_GETTER] != NULL)
+#define FUNCTION_ISA_SETTER(_f)                     (_f->special[EXEC_TYPE_SPECIAL_SETTER] != NULL)
+#define FUNCTION_ISA_BRIDGED(_f)                    (_f->index == GRAVITY_BRIDGE_INDEX)
+
 #endif
 #endif

+ 8 - 3
src/shared/gravity_value.c

@@ -358,7 +358,7 @@ abort_load:
 }
 }
 
 
 static void gravity_class_free_internal (gravity_vm *vm, gravity_class_t *c, bool skip_base) {
 static void gravity_class_free_internal (gravity_vm *vm, gravity_class_t *c, bool skip_base) {
-	if (skip_base && gravity_iscore_class(c)) return;
+	if (skip_base && (gravity_iscore_class(c) || gravity_isoptional_class(c))) return;
 	
 	
 	DEBUG_FREE("FREE %s", gravity_object_debug((gravity_object_t *)c));
 	DEBUG_FREE("FREE %s", gravity_object_debug((gravity_object_t *)c));
 	
 	
@@ -845,11 +845,16 @@ gravity_function_t *gravity_function_deserialize (gravity_vm *vm, json_value *js
 		
 		
 		// bytecode
 		// bytecode
 		if (string_casencmp(label, GRAVITY_JSON_LABELBYTECODE, label_size) == 0) {
 		if (string_casencmp(label, GRAVITY_JSON_LABELBYTECODE, label_size) == 0) {
-			if (value->type == json_null) continue;
+            if (bytecode_parsed) goto abort_load;
+            if (value->type == json_null) {
+                // if function is empty then just one RET0 implicit bytecode instruction
+                f->ninsts = 0;
+                f->bytecode = (uint32_t *)mem_alloc(sizeof(uint32_t) * (f->ninsts + 1));
+            } else {
 			if (value->type != json_string) goto abort_load;
 			if (value->type != json_string) goto abort_load;
             if (f->tag != EXEC_TYPE_NATIVE) goto abort_load;
             if (f->tag != EXEC_TYPE_NATIVE) goto abort_load;
-            if (bytecode_parsed) goto abort_load;
 			f->bytecode = gravity_bytecode_deserialize(value->u.string.ptr, value->u.string.length, &f->ninsts);
 			f->bytecode = gravity_bytecode_deserialize(value->u.string.ptr, value->u.string.length, &f->ninsts);
+            }
             bytecode_parsed = true;
             bytecode_parsed = true;
 			continue;
 			continue;
 		}
 		}