diff --git a/.gitignore b/.gitignore
index a9d6a723..23f95c20 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,7 +14,8 @@ src/Amalgam/AmalgamVersion.h
.envrc
.env
-## Amalgam metadata files
+## Amalgam binary files
+*.caml
*.mdam
## Build results
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 854dc6cf..24cb8a2b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -134,6 +134,8 @@ set(COMMON_SOURCE
src/Amalgam/FilenameEscapeProcessor.h
src/Amalgam/GeneralizedDistance.h
src/Amalgam/HashMaps.h
+ src/Amalgam/importexport/FileSupportCAML.cpp
+ src/Amalgam/importexport/FileSupportCAML.h
src/Amalgam/importexport/FileSupportCSV.cpp
src/Amalgam/importexport/FileSupportCSV.h
src/Amalgam/importexport/FileSupportJSON.cpp
@@ -176,8 +178,6 @@ set(COMMON_SOURCE
src/Amalgam/string/StringInternPool.h
src/Amalgam/string/StringManipulation.cpp
src/Amalgam/string/StringManipulation.h
- # Add out.txt so it shows up in IDE
- src/Amalgam/out.txt
)
set(COMMON_SOURCE_THREADS
${COMMON_SOURCE}
@@ -206,6 +206,8 @@ source_group(TREE ${CMAKE_SOURCE_DIR} FILES ${AMALGAM_ALL_SOURCE})
# Get all files we care about for easy access in projects (mainly IDEs)
file(GLOB_RECURSE ALL_FILES "${CMAKE_SOURCE_DIR}/*")
list(FILTER ALL_FILES EXCLUDE REGEX "(.*/.git/.*|.*/out/.*|.*/src/.*|.*/test/.*|.*Amalgam\.sln.*)")
+file(GLOB_RECURSE ADDITIONAL_FILES "${CMAKE_SOURCE_DIR}/src/Amalgam/out.txt" "${CMAKE_SOURCE_DIR}/src/Amalgam/amlg_code/*")
+list(APPEND ALL_FILES ${ADDITIONAL_FILES})
source_group(TREE ${CMAKE_SOURCE_DIR} FILES ${ALL_FILES})
list(APPEND AMALGAM_APP_ONLY_SOURCE ${ALL_FILES})
diff --git a/docs/language.js b/docs/language.js
index bd9e1dda..eebc7a51 100644
--- a/docs/language.js
+++ b/docs/language.js
@@ -1332,7 +1332,7 @@ var data = [
"parameter" : "load string file_path [bool escape_filename] [string file_type]",
"output" : "*",
"permissions" : "r",
- "description" : "Loads the data specified by the resource in string. Attempts to load the file type and parse it into appropriate data and evaluate to the corresponding code. The parameter escape_filename defaults to false, but if it is true, it will agressively escape filenames using only alphanumeric characters and the underscore, using underscore as an escape character. If file_type is specified and not null, it will use the file_type specified instead of the extension of the file_path. File formats supported are amlg, json, yaml, csv, cstl, and caml; anything not in this list will be loaded as a binary string. Note that loading from a non-'.amlg' extension will only ever provide lists, assocs, numbers, and strings.",
+ "description" : "Loads the data specified by the resource in string. Attempts to load the file type and parse it into appropriate data and evaluate to the corresponding code. The parameter escape_filename defaults to false, but if it is true, it will agressively escape filenames using only alphanumeric characters and the underscore, using underscore as an escape character. If file_type is specified and not null, it will use the file_type specified instead of the extension of the file_path. File formats supported are amlg, json, yaml, csv, and caml; anything not in this list will be loaded as a binary string. Note that loading from a non-'.amlg' extension will only ever provide lists, assocs, numbers, and strings.",
"example" : "(print (load \"my_directory/MyModule.amlg\"))"
},
@@ -1340,7 +1340,7 @@ var data = [
"parameter" : "load_entity string file_path [id entity] [bool escape_filename] [bool escape_contained_filenames] [string file_type]",
"output" : "id",
"permissions" : "r",
- "description" : "Loads an entity specified by the resource in string. Attempts to load the file type and parse it into appropriate data and store it in the entity specified by id, following the same id creation rules as create_entities, except that if no id is specified, it may default to a name based on the resource if available. The parameter escape_filename defaults to false, but if it is true, it will agressively escape filenames using only alphanumeric characters and the underscore, using underscore as an escape character. If escape_contained_filenames is true, which is its default, it will also escape contained entity filenames. If file_type is specified and not null, it will use the file_type specified instead of the extension of the file_path. File formats supported are amlg, json, yaml, csv, cstl, and caml; anything not in this list will be loaded as a binary string. Note that loading from a non-'.amlg' extension will only ever provide lists, assocs, numbers, and strings.",
+ "description" : "Loads an entity specified by the resource in string. Attempts to load the file type and parse it into appropriate data and store it in the entity specified by id, following the same id creation rules as create_entities, except that if no id is specified, it may default to a name based on the resource if available. The parameter escape_filename defaults to false, but if it is true, it will agressively escape filenames using only alphanumeric characters and the underscore, using underscore as an escape character. If escape_contained_filenames is true, which is its default, it will also escape contained entity filenames. If file_type is specified and not null, it will use the file_type specified instead of the extension of the file_path. File formats supported are amlg, json, yaml, csv, and caml; anything not in this list will be loaded as a binary string. Note that loading from a non-'.amlg' extension will only ever provide lists, assocs, numbers, and strings.",
"example" : "(load_entity \"my_directory/MyModule.amlg\" \"MyModule\")"
},
@@ -1348,7 +1348,7 @@ var data = [
"parameter" : "load_persistent_entity string file_path [id entity] [bool escape_filename]",
"output" : "id",
"permissions" : "r",
- "description" : "Loads an entity specified by the resource in string. Attempts to load the file type and parse it into appropriate data and store it in the entity specified by id, following the same id creation rules as create_entities. Any modifications to the entity or any entity contained within it will be written out to the resource, so that the memory and persistent storage are synchronized. The parameter escape_filename defaults to false, but if it is true, it will agressively escape filenames using only alphanumeric characters and the underscore, using underscore as an escape character. This command will escape contained filenames. The file type of a persisted entity must match the extension of the file of the main entity. File formats supported are amlg, json, yaml, csv, cstl, and caml; anything not in this list will be loaded as a binary string. Note that loading from a non-'.amlg' extension will only ever provide lists, assocs, numbers, and strings.\n\nWARNING: Loading the same file as a persistent entity in more than one place will overwrite the file each time either entity is altered, but changes will not be propogated between the entities.",
+ "description" : "Loads an entity specified by the resource in string. Attempts to load the file type and parse it into appropriate data and store it in the entity specified by id, following the same id creation rules as create_entities. Any modifications to the entity or any entity contained within it will be written out to the resource, so that the memory and persistent storage are synchronized. The parameter escape_filename defaults to false, but if it is true, it will agressively escape filenames using only alphanumeric characters and the underscore, using underscore as an escape character. This command will escape contained filenames. The file type of a persisted entity must match the extension of the file of the main entity. File formats supported are amlg, json, yaml, csv, and caml; anything not in this list will be loaded as a binary string. Note that loading from a non-'.amlg' extension will only ever provide lists, assocs, numbers, and strings.\n\nWARNING: Loading the same file as a persistent entity in more than one place will overwrite the file each time either entity is altered, but changes will not be propogated between the entities.",
"example" : "(load_persistent_entity \"my_directory/MyModule.amlg\" \"MyModule\")"
},
@@ -1356,7 +1356,7 @@ var data = [
"parameter" : "store string file_path * node [bool escape_filename] [string file_type] [assoc params]",
"output" : "bool",
"permissions" : "r",
- "description" : "Stores the code specified by * to the resource in string. Returns true if successful, false if not. The parameter escape_filename defaults to false, but if it is true, it will agressively escape filenames using only alphanumeric characters and the underscore, using underscore as an escape character. If file_type is specified and not null, it will use the file_type specified instead of the extension of the file_path. File formats supported are amlg, json, yaml, csv, cstl, and caml; anything not in this list will be loaded as a binary string. Note that loading from a non-'.amlg' extension will only ever provide lists, assocs, numbers, and strings. If params is specified, it is an assoc that contains key-value pairs describing the format. The key \"sort_keys\" can be used to specify a boolean value, if true, then it will sort the keys, otherwise the default behavior is to emit the keys based on memory layout.",
+ "description" : "Stores the code specified by * to the resource in string. Returns true if successful, false if not. The parameter escape_filename defaults to false, but if it is true, it will agressively escape filenames using only alphanumeric characters and the underscore, using underscore as an escape character. If file_type is specified and not null, it will use the file_type specified instead of the extension of the file_path. File formats supported are amlg, json, yaml, csv, and caml; anything not in this list will be loaded as a binary string. Note that loading from a non-'.amlg' extension will only ever provide lists, assocs, numbers, and strings. If params is specified, it is an assoc that contains key-value pairs describing the format. The key \"sort_keys\" can be used to specify a boolean value, if true, then it will sort the keys, otherwise the default behavior is to emit the keys based on memory layout.",
"example" : "(store \"my_directory/MyData.amlg\" (list 1 2 3))"
},
@@ -1364,7 +1364,7 @@ var data = [
"parameter" : "store_entity string file_path id entity [bool escape_filename] [bool escape_contained_filenames] [string file_type] [assoc params]",
"output" : "bool",
"permissions" : "r",
- "description" : "Stores the entity specified by the id to the resource in string. Returns true if successful, false if not. The parameter escape_filename defaults to false, but if it is true, it will agressively escape filenames using only alphanumeric characters and the underscore, using underscore as an escape character. If escape_contained_filenames is true, which is its default, it will also escape contained entity filenames. If file_type is specified and not null, it will use the file_type specified instead of the extension of the file_path. File formats supported are amlg, json, yaml, csv, cstl, and caml; anything not in this list will be loaded as a binary string. Note that loading from a non-'.amlg' extension will only ever provide lists, assocs, numbers, and strings. If params is specified, it is an assoc that contains key-value pairs describing the format. The key \"sort_keys\" can be used to specify a boolean value, if true, then it will sort the keys, otherwise the default behavior is to emit the keys based on memory layout.",
+ "description" : "Stores the entity specified by the id to the resource in string. Returns true if successful, false if not. The parameter escape_filename defaults to false, but if it is true, it will agressively escape filenames using only alphanumeric characters and the underscore, using underscore as an escape character. If escape_contained_filenames is true, which is its default, it will also escape contained entity filenames. If file_type is specified and not null, it will use the file_type specified instead of the extension of the file_path. File formats supported are amlg, json, yaml, csv, and caml; anything not in this list will be loaded as a binary string. Note that loading from a non-'.amlg' extension will only ever provide lists, assocs, numbers, and strings. If params is specified, it is an assoc that contains key-value pairs describing the format. The key \"sort_keys\" can be used to specify a boolean value, if true, then it will sort the keys, otherwise the default behavior is to emit the keys based on memory layout.",
"example" : "(store_entity \"my_directory/MyData.amlg\" \"MyData\")"
},
diff --git a/examples/README.md b/examples/README.md
index c80ed2f2..469330f7 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -11,5 +11,6 @@ A collection of notable and neat/fun examples written in Amalgam located in dire
* [Conway's Game of Life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life)
* [Fractals](https://en.wikipedia.org/wiki/Mandelbrot_set)
-* [Quine](https://en.wikipedia.org/wiki/Quine_(computing))
* [Hello, World!](https://en.wikipedia.org/wiki/%22Hello,_World!%22_program)
+* [Quine](https://en.wikipedia.org/wiki/Quine_(computing))
+* [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)
\ No newline at end of file
diff --git a/examples/json_search/json-combine.amlg b/examples/json_search/json-combine.amlg
index 6361387f..e0b06776 100644
--- a/examples/json_search/json-combine.amlg
+++ b/examples/json_search/json-combine.amlg
@@ -1,4 +1,4 @@
-#!./amalgam-mt
+#!amalgam-mt
(seq
(declare (assoc
file_a (get argv 1)
diff --git a/examples/repl/repl.amlg b/examples/repl/repl.amlg
new file mode 100644
index 00000000..e026a570
--- /dev/null
+++ b/examples/repl/repl.amlg
@@ -0,0 +1,7 @@
+(while (true)
+ (system "printline" "> ")
+ (let
+ (assoc input (system "readline") )
+ (print (call (parse input)) "\n")
+ )
+)
\ No newline at end of file
diff --git a/src/Amalgam/Amalgam.h b/src/Amalgam/Amalgam.h
index 17e4c9bc..2208cd2e 100644
--- a/src/Amalgam/Amalgam.h
+++ b/src/Amalgam/Amalgam.h
@@ -1,7 +1,8 @@
#pragma once
//system headers:
-#include
+#include
+#include
#if defined(_MSC_VER)
//Microsoft
@@ -15,8 +16,19 @@
extern "C"
{
+ //status from LoadEntity
+ struct LoadEntityStatus
+ {
+ bool loaded;
+ char *message;
+ char *version;
+ };
+
//loads the entity specified into handle
- AMALGAM_EXPORT bool LoadEntity(char *handle, char *path, bool persistent, bool load_contained_entities, char *write_log_filename, char *print_log_filename);
+ AMALGAM_EXPORT LoadEntityStatus LoadEntity(char *handle, char *path, bool persistent, bool load_contained_entities, char *write_log_filename, char *print_log_filename);
+
+ //verifies the entity specified by path. Uses LoadEntityStatus to return any errors and version
+ AMALGAM_EXPORT LoadEntityStatus VerifyEntity(char *path);
//stores the entity specified by handle into path
AMALGAM_EXPORT void StoreEntity(char *handle, char *path, bool update_persistence_location = false, bool store_contained_entities = true);
@@ -37,7 +49,6 @@ extern "C"
AMALGAM_EXPORT void AppendNumberValue(char *handle, char *label, double value);
AMALGAM_EXPORT void SetNumberValue(char *handle, char *label, double value);
- AMALGAM_EXPORT size_t PrepStringValueToTransferBuffer(char *handle, char *label);
AMALGAM_EXPORT void AppendStringValue(char *handle, char *label, char *value);
AMALGAM_EXPORT void SetStringValue(char *handle, char *label, char *value);
@@ -55,7 +66,7 @@ extern "C"
AMALGAM_EXPORT void AppendStringList(char *handle, char *label, char **list, size_t len);
AMALGAM_EXPORT void SetStringList(char *handle, char *label, char **list, size_t len);
- AMALGAM_EXPORT void SetJSONToLabel(char *handle, char *label, char *json);
+ AMALGAM_EXPORT void SetJSONToLabel(char *handle, char *label, char *json);
AMALGAM_EXPORT wchar_t *GetJSONPtrFromLabelWide(char *handle, char *label);
AMALGAM_EXPORT char *GetJSONPtrFromLabel(char *handle, char *label);
diff --git a/src/Amalgam/Amalgam.vcxproj b/src/Amalgam/Amalgam.vcxproj
index b45ad26d..402e8eec 100644
--- a/src/Amalgam/Amalgam.vcxproj
+++ b/src/Amalgam/Amalgam.vcxproj
@@ -569,6 +569,7 @@
+
@@ -634,6 +635,7 @@
+
diff --git a/src/Amalgam/Amalgam.vcxproj.filters b/src/Amalgam/Amalgam.vcxproj.filters
index 818c83f1..7e94ccea 100644
--- a/src/Amalgam/Amalgam.vcxproj.filters
+++ b/src/Amalgam/Amalgam.vcxproj.filters
@@ -42,6 +42,9 @@
Source Files
+
+ Source Files
+
Source Files
@@ -191,6 +194,9 @@
Header Files
+
+ Header Files
+
Header Files
diff --git a/src/Amalgam/AmalgamAPI.cpp b/src/Amalgam/AmalgamAPI.cpp
index 98eec179..7ab224a6 100644
--- a/src/Amalgam/AmalgamAPI.cpp
+++ b/src/Amalgam/AmalgamAPI.cpp
@@ -6,11 +6,6 @@
#include "EntityQueries.h"
//system headers:
-#include
-#include
-#include
-#include
-#include