Browse Source

Sol Part 24: Harry Kwanzuhannamas!

Graham Northup 6 years ago
parent
commit
4df3383ccc
10 changed files with 938 additions and 139 deletions
  1. 1
    0
      .gitignore
  2. 1
    1
      astprint.c
  3. 1
    2
      build.sh
  4. 335
    26
      builtins.c
  5. 0
    1
      dummypow.c
  6. 169
    6
      object.c
  7. 5
    1
      runtime.c
  8. 107
    4
      sol.h
  9. 268
    98
      state.c
  10. 51
    0
      test.sol

+ 1
- 0
.gitignore View File

@@ -1,2 +1,3 @@
1 1
 sol
2 2
 *.o
3
+stdout

+ 1
- 1
astprint.c View File

@@ -8,7 +8,7 @@ void prlev(int lev, const char *fmt, ...) {
8 8
 	va_list vl;
9 9
 	int i;
10 10
 
11
-	for(i = 0; i < lev; i++) putchar('\t');
11
+	for(i = 0; i < lev; i++) { putchar('|'); putchar(' '); }
12 12
 	va_start(vl, fmt);
13 13
 	vprintf(fmt, vl);
14 14
 	va_end(vl);

+ 1
- 2
build.sh View File

@@ -10,5 +10,4 @@ gcc -c -g object.c
10 10
 gcc -c -g state.c
11 11
 gcc -c -g builtins.c
12 12
 gcc -c -g solrun.c
13
-gcc -c -g dummypow.c
14
-gcc -g -lm *.o -o sol
13
+gcc -g *.o -o sol -lm -ldl

+ 335
- 26
builtins.c View File

@@ -3,11 +3,14 @@
3 3
 #include <stdio.h>
4 4
 #include <math.h>
5 5
 #include <stdint.h>
6
+#include <dlfcn.h>
6 7
 #include "ast.h"
7 8
 #include "dsl/dsl.h"
8 9
 
9 10
 // XXX hardcoded buffer sizes
10 11
 
12
+#define STDIO_CHUNK_SIZE 4096
13
+
11 14
 static char *_itoa(int i) {
12 15
 	int n = 33;
13 16
 	char *s = malloc(n);
@@ -34,6 +37,20 @@ sol_object_t *sol_f_default_cmp(sol_state_t *state, sol_object_t *args) {
34 37
     return res;
35 38
 }
36 39
 
40
+sol_object_t *sol_f_default_tostring(sol_state_t *state, sol_object_t *args) {
41
+	sol_object_t *obj = sol_list_get_index(state, args, 0);
42
+	char s[64];
43
+	snprintf(s, 64, "<%s object at %p>", obj->ops->tname, obj);
44
+	sol_obj_free(obj);
45
+	return sol_new_string(state, s);
46
+}
47
+
48
+sol_object_t *sol_f_default_repr(sol_state_t *state, sol_object_t *args) {
49
+	sol_object_t *obj = sol_list_get_index(state, args, 0), *res = obj->ops->tostring(state, args);
50
+	sol_obj_free(obj);
51
+	return res;
52
+}
53
+
37 54
 sol_object_t *sol_f_no_op(sol_state_t *state, sol_object_t *args) {
38 55
 	if(state) return sol_incref(state->None);
39 56
 	return NULL;
@@ -94,33 +111,38 @@ sol_object_t *sol_f_error(sol_state_t *state, sol_object_t *args) {
94 111
 	return res;
95 112
 }
96 113
 
97
-static char *sol_TypeNames[] = {"singlet", "integer", "float", "string", "list", "map", "mapcell", "function", "cfunction", "cdata"};
98
-
99 114
 sol_object_t *sol_f_type(sol_state_t *state, sol_object_t *args) {
100 115
     sol_object_t *obj = sol_list_get_index(state, args, 0);
101
-    sol_object_t *res = sol_new_string(state, sol_TypeNames[obj->type]);
116
+    sol_object_t *res = sol_new_string(state, obj->ops->tname);
102 117
     sol_obj_free(obj);
103 118
     return res;
104 119
 }
105 120
 
106 121
 static dsl_seq *seen=NULL;
107 122
 
108
-void ob_print(sol_object_t *obj) {
109
-    sol_object_t *cur;
123
+int test_seen(sol_object_t *obj) {
110 124
 	dsl_seq_iter *iter;
111
-	int i;
112 125
 	if(seen) {
113 126
 		iter = dsl_new_seq_iter(seen);
114 127
 		while(!dsl_seq_iter_is_invalid(iter)) {
115 128
 			if(dsl_seq_iter_at(iter) == obj) {
116
-				printf("... (%p)", obj);
117
-				return;
129
+				return 1;
118 130
 			}
119 131
 			dsl_seq_iter_next(iter);
120 132
 		}
121 133
 		dsl_free_seq_iter(iter);
122 134
 		dsl_seq_insert(seen, dsl_seq_len(seen), obj);
123 135
 	}
136
+	return 0;
137
+}
138
+
139
+void ob_print(sol_object_t *obj) {
140
+    sol_object_t *cur;
141
+	dsl_seq_iter *iter;
142
+	int i;
143
+	if(test_seen(obj)) {
144
+		return;
145
+	}
124 146
     switch(obj->type) {
125 147
         case SOL_SINGLET:
126 148
             printf("%s", obj->str);
@@ -223,25 +245,25 @@ sol_object_t *sol_f_prepr(sol_state_t *state, sol_object_t *args) {
223 245
 	}
224 246
 	printf("\n");
225 247
 	dsl_free_seq(seen);
248
+	seen = NULL;
226 249
     return sol_incref(state->None);
227 250
 }
228 251
 
229 252
 sol_object_t *sol_f_print(sol_state_t *state, sol_object_t *args) {
230 253
 	int i, sz = sol_list_len(state, args);
231
-    sol_object_t *obj;
254
+    sol_object_t *obj, *str;
232 255
 	seen = dsl_seq_new_array(NULL, NULL);
233 256
 	for(i=0; i<sz; i++) {
234 257
 		obj = sol_list_get_index(state, args, i);
235
-		if(sol_is_string(obj)) {
236
-			printf("%s", obj->str);
237
-		} else {
238
-			ob_print(obj);
239
-		}
240
-		printf(" ");
258
+		str = sol_cast_string(state, obj);
259
+		sol_printf(state, "%s", str->str);
260
+		sol_printf(state, " ");
241 261
 		sol_obj_free(obj);
262
+		sol_obj_free(str);
242 263
 	}
243
-	printf("\n");
264
+	sol_printf(state, "\n");
244 265
 	dsl_free_seq(seen);
266
+	seen = NULL;
245 267
     return sol_incref(state->None);
246 268
 }
247 269
 
@@ -455,6 +477,12 @@ sol_object_t *sol_f_iter_map(sol_state_t *state, sol_object_t *args) {
455 477
 	return res;
456 478
 }
457 479
 
480
+sol_object_t *sol_f_singlet_tostring(sol_state_t *state, sol_object_t *args) {
481
+	sol_object_t *obj = sol_list_get_index(state, args, 0), *res = sol_new_string(state, obj->str);
482
+	sol_obj_free(obj);
483
+	return res;
484
+}
485
+
458 486
 sol_object_t *sol_f_int_add(sol_state_t *state, sol_object_t *args) {
459 487
 	sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_int(state, sol_list_get_index(state, args, 1));
460 488
 	sol_object_t *res = sol_new_int(state, a->ival + b->ival);
@@ -664,12 +692,9 @@ sol_object_t *sol_f_float_tostring(sol_state_t *state, sol_object_t *args) {
664 692
 
665 693
 sol_object_t *sol_f_str_add(sol_state_t *state, sol_object_t *args) {
666 694
 	sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_cast_string(state, sol_list_get_index(state, args, 1));
667
-	int n = strlen(a->str) + strlen(b->str) + 1;
668
-	char *s = malloc(n);
669
-	sol_object_t *res = sol_new_string(state, strncat(strncpy(s, a->str, n), b->str, n));
695
+	sol_object_t *res = sol_string_concat(state, a, b);
670 696
 	sol_obj_free(a);
671 697
 	sol_obj_free(b);
672
-	free(s);
673 698
 	if(sol_has_error(state)) {sol_obj_free(res); return sol_incref(state->None);}
674 699
 	return res;
675 700
 }
@@ -738,6 +763,15 @@ sol_object_t *sol_f_str_tostring(sol_state_t *state, sol_object_t *args) {
738 763
 	return sol_list_get_index(state, args, 0);
739 764
 }
740 765
 
766
+sol_object_t *sol_f_str_repr(sol_state_t *state, sol_object_t *args) {
767
+	sol_object_t *obj = sol_list_get_index(state, args, 0), *cur = sol_new_string(state, "\""), *next = sol_string_concat(state, cur, obj);
768
+	sol_obj_free(cur);
769
+	cur = next;
770
+	next = sol_string_concat_cstr(state, cur, "\"");
771
+	sol_obj_free(cur);
772
+	return next;
773
+}
774
+
741 775
 sol_object_t *sol_f_list_add(sol_state_t *state, sol_object_t *args) {
742 776
 	sol_object_t *a = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *ls;
743 777
 	if(!sol_is_list(b)) {
@@ -774,9 +808,11 @@ sol_object_t *sol_f_list_mul(sol_state_t *state, sol_object_t *args) {
774 808
 
775 809
 sol_object_t *sol_f_list_index(sol_state_t *state, sol_object_t *args) {
776 810
 	sol_object_t *ls = sol_list_get_index(state, args, 0), *b = sol_list_get_index(state, args, 1), *ival;
777
-	sol_object_t *res;
811
+	sol_object_t *res, *funcs;
778 812
 	if(sol_is_string(b)) {
779
-        res = sol_map_get(state, state->ListFuncs, b);
813
+		funcs = sol_get_methods_name(state, "list");
814
+        res = sol_map_get(state, funcs, b);
815
+		sol_obj_free(funcs);
780 816
 	} else {
781 817
         ival = sol_cast_int(state, b);
782 818
         res = sol_list_get_index(state, ls, ival->ival);
@@ -809,7 +845,32 @@ sol_object_t *sol_f_list_iter(sol_state_t *state, sol_object_t *args) {
809 845
 }
810 846
 
811 847
 sol_object_t *sol_f_list_tostring(sol_state_t *state, sol_object_t *args) {
812
-	return sol_new_string(state, "<List>");
848
+	sol_object_t *cur = sol_new_string(state, "["), *next, *str, *obj = sol_list_get_index(state, args, 0), *item;
849
+	dsl_seq_iter *iter = dsl_new_seq_iter(obj->seq);
850
+	char s[64];
851
+	while(!dsl_seq_iter_is_invalid(iter)) {
852
+		item = AS_OBJ(dsl_seq_iter_at(iter));
853
+		if(test_seen(item)) {
854
+			snprintf(s, 64, "... (%p)", item);
855
+			next = sol_string_concat_cstr(state, cur, s);
856
+		} else {
857
+			str = sol_cast_repr(state, item);
858
+			next = sol_string_concat(state, cur, str);
859
+			sol_obj_free(str);
860
+		}
861
+		sol_obj_free(cur);
862
+		cur = next;
863
+		if(!dsl_seq_iter_at_end(iter)) {
864
+			next = sol_string_concat_cstr(state, cur, ", ");
865
+			sol_obj_free(cur);
866
+			cur = next;
867
+		}
868
+		dsl_seq_iter_next(iter);
869
+	}
870
+	next = sol_string_concat_cstr(state, cur, "]");
871
+	sol_obj_free(cur);
872
+	dsl_free_seq_iter(iter);
873
+	return next;
813 874
 }
814 875
 
815 876
 sol_object_t *sol_f_list_copy(sol_state_t *state, sol_object_t *args) {
@@ -986,7 +1047,62 @@ sol_object_t *sol_f_map_iter(sol_state_t *state, sol_object_t *args) {
986 1047
 }
987 1048
 
988 1049
 sol_object_t *sol_f_map_tostring(sol_state_t *state, sol_object_t *args) {
989
-	return sol_new_string(state, "<Map>");
1050
+	sol_object_t *cur = sol_new_string(state, "{"), *next, *str, *obj = sol_list_get_index(state, args, 0), *item;
1051
+	dsl_seq_iter *iter = dsl_new_seq_iter(obj->seq);
1052
+	char s[64];
1053
+	while(!dsl_seq_iter_is_invalid(iter)) {
1054
+		item = AS_OBJ(dsl_seq_iter_at(iter));
1055
+		if(test_seen(item)) {
1056
+			snprintf(s, 64, "... (%p)", item);
1057
+			next = sol_string_concat_cstr(state, cur, s);
1058
+		} else {
1059
+			str = sol_cast_repr(state, item);
1060
+			next = sol_string_concat(state, cur, str);
1061
+			sol_obj_free(str);
1062
+		}
1063
+		sol_obj_free(cur);
1064
+		cur = next;
1065
+		if(!dsl_seq_iter_at_end(iter)) {
1066
+			next = sol_string_concat_cstr(state, cur, ", ");
1067
+			sol_obj_free(cur);
1068
+			cur = next;
1069
+		}
1070
+		dsl_seq_iter_next(iter);
1071
+	}
1072
+	next = sol_string_concat_cstr(state, cur, "}");
1073
+	sol_obj_free(cur);
1074
+	dsl_free_seq_iter(iter);
1075
+	sol_obj_free(obj);
1076
+	return next;
1077
+}
1078
+
1079
+sol_object_t *sol_f_mcell_tostring(sol_state_t *state, sol_object_t *args) {
1080
+	sol_object_t *mcell = sol_list_get_index(state, args, 0), *cur = sol_new_string(state, "["), *next, *str;
1081
+	char s[64];
1082
+	if(test_seen(mcell->key)) {
1083
+		snprintf(s, 64, "... (%p)", mcell->key);
1084
+		next = sol_string_concat_cstr(state, cur, s);
1085
+	} else {
1086
+		str = sol_cast_repr(state, mcell->key);
1087
+		next = sol_string_concat(state, cur, str);
1088
+		sol_obj_free(str);
1089
+	}
1090
+	sol_obj_free(cur);
1091
+	cur = next;
1092
+	next = sol_string_concat_cstr(state, cur, "] = ");
1093
+	sol_obj_free(cur);
1094
+	cur = next;
1095
+	if(test_seen(mcell->val)) {
1096
+		snprintf(s, 64, "... (%p)", mcell->val);
1097
+		next = sol_string_concat_cstr(state, cur, s);
1098
+	} else {
1099
+		str = sol_cast_repr(state, mcell->val);
1100
+		next = sol_string_concat(state, cur, str);
1101
+		sol_obj_free(str);
1102
+	}
1103
+	sol_obj_free(cur);
1104
+	sol_obj_free(mcell);
1105
+	return next;
990 1106
 }
991 1107
 
992 1108
 sol_object_t *sol_f_func_index(sol_state_t *state, sol_object_t *args) {
@@ -1047,7 +1163,11 @@ sol_object_t *sol_f_func_setindex(sol_state_t *state, sol_object_t *args) {
1047 1163
 sol_object_t *sol_f_func_tostring(sol_state_t *state, sol_object_t *args) {
1048 1164
 	sol_object_t *func = sol_list_get_index(state, args, 0), *ret;
1049 1165
 	char *s = malloc(256 * sizeof(char));
1050
-	snprintf(s, 256, "<Function %s>", func->fname);
1166
+	if(func->fname) {
1167
+		snprintf(s, 256, "<Function %s>", func->fname);
1168
+	} else {
1169
+		snprintf(s, 256, "<Function>");
1170
+	}
1051 1171
 	ret = sol_new_string(state, s);
1052 1172
 	free(s);
1053 1173
 	sol_obj_free(func);
@@ -1578,8 +1698,10 @@ sol_object_t *sol_f_astnode_tostring(sol_state_t *state, sol_object_t *args) {
1578 1698
 }
1579 1699
 
1580 1700
 sol_object_t *sol_f_buffer_index(sol_state_t *state, sol_object_t *args) {
1581
-	sol_object_t *key = sol_list_get_index(state, args, 1), *res = sol_map_get(state, state->BufferFuncs, key);
1701
+	sol_object_t *key = sol_list_get_index(state, args, 1), *funcs = sol_get_methods_name(state, "buffer");
1702
+	sol_object_t *res = sol_map_get(state, funcs, key);
1582 1703
 	sol_obj_free(key);
1704
+	sol_obj_free(funcs);
1583 1705
 	return res;
1584 1706
 }
1585 1707
 
@@ -1872,4 +1994,191 @@ sol_object_t *sol_f_buffer_fromaddress(sol_state_t *state, sol_object_t *args) {
1872 1994
 	sol_obj_free(iaddr);
1873 1995
 	sol_obj_free(isz);
1874 1996
 	return buf;
1997
+}
1998
+
1999
+sol_object_t *sol_f_dylib_index(sol_state_t *state, sol_object_t *args) {
2000
+	sol_object_t *dylib = sol_list_get_index(state, args, 0), *key = sol_list_get_index(state, args, 1), *skey = sol_cast_string(state, key);
2001
+	void *handle = dlsym(dylib->dlhandle, skey->str);
2002
+	sol_obj_free(dylib);
2003
+	sol_obj_free(key);
2004
+	sol_obj_free(skey);
2005
+	if(handle) {
2006
+		return sol_new_dysym(state, handle, NULL, BUF_NONE);
2007
+	} else {
2008
+		return sol_incref(state->None);
2009
+	}
2010
+}
2011
+
2012
+sol_object_t *sol_f_dylib_tostring(sol_state_t *state, sol_object_t *args) {
2013
+	return sol_new_string(state, "<DyLib>");
2014
+}
2015
+
2016
+sol_object_t *sol_f_dysym_call(sol_state_t *state, sol_object_t *args) {
2017
+	//TODO
2018
+	return sol_incref(state->None);
2019
+}
2020
+
2021
+sol_object_t *sol_f_dysym_index(sol_state_t *state, sol_object_t *args) {
2022
+	//TODO
2023
+	return sol_incref(state->None);
2024
+}
2025
+
2026
+sol_object_t *sol_f_dysym_setindex(sol_state_t *state, sol_object_t *args) {
2027
+	//TODO
2028
+	return sol_incref(state->None);
2029
+}
2030
+
2031
+sol_object_t *sol_f_dysym_tostring(sol_state_t *state, sol_object_t *args) {
2032
+	return sol_new_string(state, "<DySym>");
2033
+}
2034
+
2035
+sol_object_t *sol_f_stream_blsh(sol_state_t *state, sol_object_t *args) {
2036
+	return sol_f_stream_write(state, args);
2037
+}
2038
+
2039
+sol_object_t *sol_f_stream_brsh(sol_state_t *state, sol_object_t *args) {
2040
+	return sol_f_stream_read(state, args);
2041
+}
2042
+
2043
+sol_object_t *sol_f_stream_index(sol_state_t *state, sol_object_t *args) {
2044
+	sol_object_t *key = sol_list_get_index(state, args, 1), *funcs = sol_get_methods_name(state, "stream");
2045
+	sol_object_t *res = sol_map_get(state, funcs, key);
2046
+	sol_obj_free(key);
2047
+	sol_obj_free(funcs);
2048
+	return res;
2049
+}
2050
+
2051
+sol_object_t *sol_f_stream_tostring(sol_state_t *state, sol_object_t *args) {
2052
+	return sol_new_string(state, "<Stream>");
2053
+}
2054
+
2055
+sol_object_t *sol_f_stream_write(sol_state_t *state, sol_object_t *args) {
2056
+	sol_object_t *stream = sol_list_get_index(state, args, 0), *obj = sol_list_get_index(state, args, 1), *str = sol_cast_string(state, obj);
2057
+	size_t sz = sol_stream_printf(state, stream, "%s", str->str);
2058
+	sol_obj_free(obj);
2059
+	sol_obj_free(str);
2060
+	sol_obj_free(stream);
2061
+	return sol_new_int(state, sz);
2062
+}
2063
+
2064
+sol_object_t *sol_f_stream_read(sol_state_t *state, sol_object_t *args) {
2065
+	sol_object_t *stream = sol_list_get_index(state, args, 0), *amt = sol_list_get_index(state, args, 1), *iamt, *res;
2066
+	char *s=NULL, *p;
2067
+	size_t count=0, max=0, pos, end;
2068
+	if(sol_is_string(amt)) {
2069
+		if(sol_string_eq(state, amt, "ALL")) {
2070
+			pos = sol_stream_ftell(state, stream);
2071
+			sol_stream_fseek(state, stream, 0, SEEK_END);
2072
+			end = sol_stream_ftell(state, stream);
2073
+			sol_stream_fseek(state, stream, pos, SEEK_SET);
2074
+			//printf("IO: Reading %ld bytes starting at %ld\n", end-pos, pos);
2075
+			s = malloc((end-pos+1)*sizeof(char));
2076
+			if(sol_stream_fread(state, stream, s, sizeof(char), end-pos)<(end-pos)) {
2077
+				free(s);
2078
+				sol_obj_free(stream);
2079
+				sol_obj_free(amt);
2080
+				return sol_set_error_string(state, "IO read error");
2081
+			}
2082
+			s[end-pos]='\0';
2083
+		} else if(sol_string_eq(state, amt, "LINE")) {
2084
+			s = malloc(STDIO_CHUNK_SIZE*sizeof(char));
2085
+			sol_stream_fgets(state, stream, s, STDIO_CHUNK_SIZE);
2086
+		}
2087
+	} else {
2088
+		iamt = sol_cast_int(state, amt);
2089
+		s = malloc((iamt->ival + 1)*sizeof(char));
2090
+		count = sol_stream_fread(state, stream, s, sizeof(char), iamt->ival);
2091
+		s[iamt->ival]='\0';
2092
+		sol_obj_free(iamt);
2093
+	}
2094
+	if(s) {
2095
+		//printf("IO: Read result: %s\n", s);
2096
+		res = sol_new_string(state, s);
2097
+		free(s);
2098
+	} else {
2099
+		//printf("IO: No read result!\n");
2100
+		res = sol_incref(state->None);
2101
+	}
2102
+	sol_obj_free(amt);
2103
+	sol_obj_free(stream);
2104
+	return res;
2105
+}
2106
+
2107
+sol_object_t *sol_f_stream_seek(sol_state_t *state, sol_object_t *args) {
2108
+	sol_object_t *stream = sol_list_get_index(state, args, 0), *offset = sol_list_get_index(state, args, 1), *whence = sol_list_get_index(state, args, 2);
2109
+	sol_object_t *ioffset = sol_cast_int(state, offset), *iwhence = sol_cast_int(state, whence);
2110
+	sol_object_t *res = sol_new_int(state, sol_stream_fseek(state, stream, ioffset->ival, iwhence->ival));
2111
+	sol_obj_free(stream);
2112
+	sol_obj_free(offset);
2113
+	sol_obj_free(whence);
2114
+	sol_obj_free(ioffset);
2115
+	sol_obj_free(iwhence);
2116
+	return res;
2117
+}
2118
+
2119
+sol_object_t *sol_f_stream_tell(sol_state_t *state, sol_object_t *args) {
2120
+	sol_object_t *stream = sol_list_get_index(state, args, 0), *res = sol_new_int(state, sol_stream_ftell(state, stream));
2121
+	sol_obj_free(stream);
2122
+	return res;
2123
+}
2124
+
2125
+sol_object_t *sol_f_stream_flush(sol_state_t *state, sol_object_t *args) {
2126
+	sol_object_t *stream = sol_list_get_index(state, args, 0), *res = sol_new_int(state, sol_stream_fflush(state, stream));
2127
+	sol_obj_free(stream);
2128
+	return res;
2129
+}
2130
+
2131
+static char *sol_FileModes[]={
2132
+	NULL,
2133
+	"r",
2134
+	"w",
2135
+	"r+",
2136
+	NULL,
2137
+	NULL,
2138
+	"a",
2139
+	"a+",
2140
+	NULL,
2141
+	NULL,
2142
+	"w",
2143
+	"w+",
2144
+	NULL,
2145
+	NULL,
2146
+	NULL,
2147
+	NULL,
2148
+	NULL,
2149
+	"rb",
2150
+	"wb",
2151
+	"r+b",
2152
+	NULL,
2153
+	NULL,
2154
+	"ab",
2155
+	"a+b",
2156
+	NULL,
2157
+	NULL,
2158
+	"wb",
2159
+	"w+b",
2160
+	NULL,
2161
+	NULL,
2162
+	NULL,
2163
+	NULL
2164
+};
2165
+
2166
+sol_object_t *sol_f_stream_open(sol_state_t *state, sol_object_t *args) {
2167
+	sol_object_t *fn = sol_list_get_index(state, args, 0), *mode = sol_list_get_index(state, args, 1);
2168
+	sol_object_t *sfn = sol_cast_string(state, fn), *imode = sol_cast_int(state, mode);
2169
+	sol_modes_t m = imode->ival;
2170
+	char *smode = sol_FileModes[m];
2171
+	FILE *f;
2172
+	sol_obj_free(mode);
2173
+	sol_obj_free(imode);
2174
+	if(!smode) {
2175
+		sol_obj_free(fn);
2176
+		sol_obj_free(sfn);
2177
+		return sol_set_error_string(state, "Bad file open mode");
2178
+	}
2179
+	f = fopen(sfn->str, smode);
2180
+	sol_obj_free(sfn);
2181
+	sol_obj_free(fn);
2182
+	if(!f) return sol_set_error_string(state, "File open failed");
2183
+	return sol_new_stream(state, f, m);
1875 2184
 }

+ 0
- 1
dummypow.c View File

@@ -1 +0,0 @@
1
-double pow(double a, double b) { return 0.0; }

+ 169
- 6
object.c View File

@@ -4,6 +4,8 @@
4 4
 #include <string.h>
5 5
 #include <stdio.h>
6 6
 #include <assert.h>
7
+#include <dlfcn.h>
8
+#include <stdarg.h>
7 9
 
8 10
 sol_object_t *sol_cast_int(sol_state_t *state, sol_object_t *obj) {
9 11
 	sol_object_t *res, *ls;
@@ -12,7 +14,6 @@ sol_object_t *sol_cast_int(sol_state_t *state, sol_object_t *obj) {
12 14
 	sol_list_insert(state, ls, 0, obj);
13 15
 	res = obj->ops->toint(state, ls);
14 16
 	sol_obj_free(ls);
15
-	sol_obj_free(obj);
16 17
 	return res;
17 18
 }
18 19
 
@@ -23,7 +24,6 @@ sol_object_t *sol_cast_float(sol_state_t *state, sol_object_t *obj) {
23 24
 	sol_list_insert(state, ls, 0, obj);
24 25
 	res = obj->ops->tofloat(state, ls);
25 26
 	sol_obj_free(ls);
26
-	sol_obj_free(obj);
27 27
 	return res;
28 28
 }
29 29
 
@@ -34,7 +34,14 @@ sol_object_t *sol_cast_string(sol_state_t *state, sol_object_t *obj) {
34 34
 	sol_list_insert(state, ls, 0, obj);
35 35
 	res = obj->ops->tostring(state, ls);
36 36
 	sol_obj_free(ls);
37
-	sol_obj_free(obj);
37
+	return res;
38
+}
39
+
40
+sol_object_t *sol_cast_repr(sol_state_t *state, sol_object_t *obj) {
41
+	sol_object_t *res, *ls = sol_new_list(state);
42
+	sol_list_insert(state, ls, 0, obj);
43
+	res = obj->ops->repr(state, ls);
44
+	sol_obj_free(ls);
38 45
 	return res;
39 46
 }
40 47
 
@@ -45,7 +52,7 @@ sol_object_t *sol_new_singlet(sol_state_t *state, const char *name) {
45 52
 	if(res) {
46 53
 		res->type = SOL_SINGLET;
47 54
 		res->refcnt = 0;
48
-		res->ops = &(state->NullOps);
55
+		res->ops = &(state->SingletOps);
49 56
 		res->str = strdup(name);
50 57
 	}
51 58
 	return sol_incref(res);
@@ -139,6 +146,24 @@ int sol_string_cmp(sol_state_t *state, sol_object_t *str, const char *s) {
139 146
 	return strcmp(str->str, s);
140 147
 }
141 148
 
149
+sol_object_t *sol_string_concat(sol_state_t *state, sol_object_t *a, sol_object_t *b) {
150
+	sol_object_t *res, *sa = sol_cast_string(state, a), *sb = sol_cast_string(state, b);
151
+	int n = strlen(sa->str) + strlen(sb->str) + 1;
152
+	char *s = malloc(n);
153
+	res = sol_new_string(state, strncat(strncpy(s, a->str, n), b->str, n));
154
+	sol_obj_free(sa);
155
+	sol_obj_free(sb);
156
+	free(s);
157
+	return res;
158
+}
159
+
160
+sol_object_t *sol_string_concat_cstr(sol_state_t *state, sol_object_t *a, char *s) {
161
+	sol_object_t *b = sol_new_string(state, s);
162
+	sol_object_t *res = sol_string_concat(state, a, b);
163
+	sol_obj_free(b);
164
+	return res;
165
+}
166
+
142 167
 sol_object_t *sol_f_str_free(sol_state_t *state, sol_object_t *obj) {
143 168
 	free(obj->str);
144 169
 	return obj;
@@ -288,6 +313,7 @@ sol_object_t *sol_new_map(sol_state_t *state) {
288 313
     map->type = SOL_MAP;
289 314
     map->ops = &(state->MapOps);
290 315
     map->seq = dsl_seq_new_array(NULL, &(state->obfuncs));
316
+	sol_init_object(state, map);
291 317
     return map;
292 318
 }
293 319
 
@@ -305,8 +331,14 @@ int sol_map_len(sol_state_t *state, sol_object_t *map) {
305 331
 }
306 332
 
307 333
 sol_object_t *sol_map_mcell(sol_state_t *state, sol_object_t *map, sol_object_t *key) {
308
-    sol_object_t *list = sol_new_list(state), *cmp, *icmp, *res = NULL;
309
-	dsl_seq_iter *iter = dsl_new_seq_iter(map->seq);
334
+    sol_object_t *list, *cmp, *icmp, *res = NULL;
335
+	dsl_seq_iter *iter;
336
+	if(!sol_is_map(map)) {
337
+		printf("WARNING: Attempt to index non-map as map\n");
338
+		return sol_incref(state->None);
339
+	}
340
+	list = sol_new_list(state);
341
+	iter = dsl_new_seq_iter(map->seq);
310 342
 	if(sol_has_error(state)) {
311 343
 		dsl_free_seq_iter(iter);
312 344
 		sol_obj_free(list);
@@ -406,6 +438,19 @@ void sol_map_merge_existing(sol_state_t *state, sol_object_t *dest, sol_object_t
406 438
 	dsl_free_seq_iter(iter);
407 439
 }
408 440
 
441
+void sol_map_invert(sol_state_t *state, sol_object_t *map) {
442
+	dsl_seq *pairs = dsl_seq_copy(map->seq);
443
+	dsl_seq_iter *iter = dsl_new_seq_iter(pairs);
444
+	sol_object_t *mcell;
445
+	while(!dsl_seq_iter_is_invalid(iter)) {
446
+		mcell = dsl_seq_iter_at(iter);
447
+		sol_map_set(state, map, mcell->val, mcell->key);
448
+		dsl_seq_iter_next(iter);
449
+	}
450
+	dsl_free_seq_iter(iter);
451
+	dsl_free_seq(pairs);
452
+}
453
+
409 454
 sol_object_t *sol_f_map_free(sol_state_t *state, sol_object_t *map) {
410 455
     dsl_free_seq(map->seq);
411 456
     return map;
@@ -443,6 +488,7 @@ sol_object_t *sol_new_cfunc(sol_state_t *state, sol_cfunc_t cfunc) {
443 488
     res->type = SOL_CFUNCTION;
444 489
     res->ops = &(state->CFuncOps);
445 490
     res->cfunc = cfunc;
491
+	sol_init_object(state, res);
446 492
     return res;
447 493
 }
448 494
 
@@ -451,6 +497,7 @@ sol_object_t *sol_new_cdata(sol_state_t *state, void *cdata, sol_ops_t *ops) {
451 497
     res->type = SOL_CDATA;
452 498
     res->ops = ops;
453 499
     res->cdata = cdata;
500
+	sol_init_object(state, res);
454 501
     return res;
455 502
 }
456 503
 
@@ -463,6 +510,7 @@ sol_object_t *sol_new_buffer(sol_state_t *state, void *buffer, ssize_t sz, sol_o
463 510
 	res->own = own;
464 511
 	res->freef = freef;
465 512
 	res->movef = movef;
513
+	sol_init_object(state, res);
466 514
 	return res;
467 515
 }
468 516
 
@@ -478,3 +526,118 @@ sol_object_t *sol_f_buffer_free(sol_state_t *state, sol_object_t *buf) {
478 526
 	}
479 527
 	return buf;
480 528
 }
529
+
530
+sol_object_t *sol_new_dylib(sol_state_t *state, void *handle) {
531
+	sol_object_t *res = sol_alloc_object(state);
532
+	res->type = SOL_DYLIB;
533
+	res->ops = &(state->DyLibOps);
534
+	res->dlhandle = handle;
535
+	sol_init_object(state, res);
536
+	return res;
537
+}
538
+
539
+sol_object_t *sol_f_dylib_free(sol_state_t *state, sol_object_t *dylib) {
540
+	dlclose(dylib->dlhandle);
541
+	return dylib;
542
+}
543
+
544
+sol_object_t *sol_new_dysym(sol_state_t *state, void *sym, dsl_seq *argtp, sol_buftype_t rettp) {
545
+	sol_object_t *res = sol_alloc_object(state);
546
+	res->type = SOL_DYSYM;
547
+	res->ops = &(state->DySymOps);
548
+	res->dlsym = sym;
549
+	if(argtp) {
550
+		res->argtp = dsl_seq_copy(argtp);
551
+	} else {
552
+		res->argtp = dsl_seq_new_array(NULL, &(state->obfuncs));
553
+	}
554
+	res->rettp = rettp;
555
+	sol_init_object(state, res);
556
+	return res;
557
+}
558
+
559
+sol_object_t *sol_new_stream(sol_state_t *state, FILE *stream, sol_modes_t modes) {
560
+	sol_object_t *res = sol_alloc_object(state);
561
+	res->type = SOL_STREAM;
562
+	res->ops = &(state->StreamOps);
563
+	res->stream = stream;
564
+	res->modes = modes;
565
+	sol_init_object(state, res);
566
+	return res;
567
+}
568
+
569
+size_t sol_stream_printf(sol_state_t *state, sol_object_t *stream, const char *fmt, ...) {
570
+	va_list va;
571
+	size_t res;
572
+	if(!(stream->modes & MODE_WRITE)) {
573
+		sol_obj_free(sol_set_error_string(state, "Write to non-writable stream"));
574
+		return 0;
575
+	}
576
+	va_start(va, fmt);
577
+	res = vfprintf(stream->stream, fmt, va);
578
+	va_end(va);
579
+	return res;
580
+}
581
+
582
+size_t sol_stream_scanf(sol_state_t *state, sol_object_t *stream, const char *fmt, ...) {
583
+	va_list va;
584
+	size_t res;
585
+	if(!(stream->modes & MODE_READ)) {
586
+		sol_obj_free(sol_set_error_string(state, "Read from non-readable stream"));
587
+		return 0;
588
+	}
589
+	va_start(va, fmt);
590
+	res = vfscanf(stream->stream, fmt, va);
591
+	va_end(va);
592
+	return res;
593
+}
594
+
595
+size_t sol_stream_fread(sol_state_t *state, sol_object_t *stream, char *buffer, size_t sz, size_t memb) {
596
+	if(!(stream->modes & MODE_READ)) {
597
+		sol_obj_free(sol_set_error_string(state, "Read from non-readable stream"));
598
+		return 0;
599
+	}
600
+	return fread(buffer, sz, memb, stream->stream);
601
+}
602
+
603
+size_t sol_stream_fwrite(sol_state_t *state, sol_object_t *stream, char *buffer, size_t sz, size_t memb) {
604
+	if(!(stream->modes & MODE_WRITE)) {
605
+		sol_obj_free(sol_set_error_string(state, "Write to non-writable stream"));
606
+		return 0;
607
+	}
608
+	return fwrite(buffer, sz, memb, stream->stream);
609
+}
610
+
611
+char *sol_stream_fgets(sol_state_t *state, sol_object_t *stream, char *buffer, size_t sz) {
612
+	if(!(stream->modes & MODE_READ)) {
613
+		sol_obj_free(sol_set_error_string(state, "Read from non-readable stream"));
614
+		return NULL;
615
+	}
616
+	return fgets(buffer, sz, stream->stream);
617
+}
618
+
619
+int sol_stream_feof(sol_state_t *state, sol_object_t *stream) {
620
+	return feof(stream->stream);
621
+}
622
+
623
+int sol_stream_ferror(sol_state_t *state, sol_object_t *stream) {
624
+	return ferror(stream->stream);
625
+}
626
+
627
+int sol_stream_fseek(sol_state_t *state, sol_object_t *stream, long offset, int whence) {
628
+	return fseek(stream->stream, offset, whence);
629
+}
630
+
631
+long sol_stream_ftell(sol_state_t *state, sol_object_t *stream) {
632
+	return ftell(stream->stream);
633
+}
634
+
635
+int sol_stream_fflush(sol_state_t *state, sol_object_t *stream) {
636
+	return fflush(stream->stream);
637
+}
638
+
639
+sol_object_t *sol_f_stream_free(sol_state_t *state, sol_object_t *stream) {
640
+	//printf("IO: Closing open file\n");
641
+	fclose(stream->stream);
642
+	return stream;
643
+}

+ 5
- 1
runtime.c View File

@@ -252,7 +252,7 @@ sol_object_t *sol_eval_inner(sol_state_t *state, expr_node *expr, jmp_buf jmp) {
252 252
                     break;
253 253
 
254 254
                 case OP_BOR:
255
-                    res = left->ops->bor(state, list);			printf("BINOP\n"); ob_print(list); printf("\n");
255
+                    res = left->ops->bor(state, list);
256 256
                     break;
257 257
 
258 258
                 case OP_BXOR:
@@ -535,6 +535,10 @@ void sol_exec(sol_state_t *state, stmt_node *stmt) {
535 535
         case ST_BREAK:
536 536
             state->sflag = SF_BREAKING;
537 537
             break;
538
+			
539
+		default:
540
+			printf("WARNING: Unhandled statement\n");
541
+			break;
538 542
     }
539 543
 }
540 544
 

+ 107
- 4
sol.h View File

@@ -5,6 +5,7 @@
5 5
 #define NULL ((void *) 0)
6 6
 #endif
7 7
 
8
+#include <stdio.h>
8 9
 #include "dsl/dsl.h"
9 10
 
10 11
 // Forward declarations:
@@ -16,7 +17,10 @@ typedef struct sol_tag_state_t sol_state_t;
16 17
 
17 18
 typedef sol_object_t *(*sol_cfunc_t)(sol_state_t *, sol_object_t *);
18 19
 
20
+typedef void (*sol_printfunc_t)(sol_object_t *);
21
+
19 22
 typedef struct {
23
+	char *tname;
20 24
 	sol_cfunc_t add;
21 25
 	sol_cfunc_t sub;
22 26
 	sol_cfunc_t mul;
@@ -38,6 +42,7 @@ typedef struct {
38 42
 	sol_cfunc_t toint;
39 43
 	sol_cfunc_t tofloat;
40 44
 	sol_cfunc_t tostring;
45
+	sol_cfunc_t repr;
41 46
 	sol_cfunc_t init;
42 47
 	sol_cfunc_t free;
43 48
 } sol_ops_t;
@@ -55,6 +60,9 @@ typedef enum {
55 60
 	SOL_STMT,
56 61
 	SOL_EXPR,
57 62
 	SOL_BUFFER,
63
+	SOL_DYLIB,
64
+	SOL_DYSYM,
65
+	SOL_STREAM,
58 66
 	SOL_CDATA
59 67
 } sol_objtype_t;
60 68
 
@@ -86,6 +94,14 @@ typedef enum {
86 94
 	OWN_CALLF
87 95
 } sol_owntype_t;
88 96
 
97
+typedef enum {
98
+	MODE_READ = 1,
99
+	MODE_WRITE = 2,
100
+	MODE_APPEND = 4,
101
+	MODE_TRUNCATE = 8,
102
+	MODE_BINARY = 16
103
+} sol_modes_t;
104
+
89 105
 typedef void (*sol_freefunc_t)(void *, size_t);
90 106
 typedef void *(*sol_movefunc_t)(void *, size_t);
91 107
 
@@ -118,6 +134,16 @@ typedef struct sol_tag_object_t {
118 134
 			sol_freefunc_t freef;
119 135
 			sol_movefunc_t movef;
120 136
 		};
137
+		void *dlhandle;
138
+		struct {
139
+			void *dlsym;
140
+			dsl_seq *argtp;
141
+			sol_buftype_t rettp;
142
+		};
143
+		struct {
144
+			FILE *stream;
145
+			sol_modes_t modes;
146
+		};
121 147
 		void *cdata;
122 148
 	};
123 149
 } sol_object_t;
@@ -133,6 +159,7 @@ typedef struct sol_tag_state_t {
133 159
 	sol_object_t *OutOfMemory;
134 160
 	sol_object_t *StopIteration;
135 161
 	sol_ops_t NullOps;
162
+	sol_ops_t SingletOps;
136 163
 	sol_ops_t IntOps;
137 164
 	sol_ops_t FloatOps;
138 165
 	sol_ops_t StringOps;
@@ -143,8 +170,11 @@ typedef struct sol_tag_state_t {
143 170
 	sol_ops_t CFuncOps;
144 171
 	sol_ops_t ASTNodeOps;
145 172
 	sol_ops_t BufferOps;
146
-	sol_object_t *ListFuncs;
147
-	sol_object_t *BufferFuncs;
173
+	sol_ops_t DyLibOps;
174
+	sol_ops_t DySymOps;
175
+	sol_ops_t StreamOps;
176
+	sol_object_t *modules;
177
+	sol_object_t *methods;
148 178
 	dsl_object_funcs obfuncs;
149 179
 } sol_state_t;
150 180
 
@@ -168,6 +198,19 @@ sol_object_t *sol_set_error(sol_state_t *, sol_object_t *);
168 198
 sol_object_t *sol_set_error_string(sol_state_t *, const char *);
169 199
 void sol_clear_error(sol_state_t *);
170 200
 
201
+void sol_register_module(sol_state_t *, sol_object_t *, sol_object_t *);
202
+void sol_register_module_name(sol_state_t *, char *, sol_object_t *);
203
+sol_object_t *sol_get_module(sol_state_t *, sol_object_t *);
204
+sol_object_t *sol_get_module_name(sol_state_t *, char *);
205
+void sol_register_methods(sol_state_t *, sol_object_t *, sol_object_t *);
206
+void sol_register_methods_name(sol_state_t *, char *, sol_object_t *);
207
+sol_object_t *sol_get_methods(sol_state_t *, sol_object_t *);
208
+sol_object_t *sol_get_methods_name(sol_state_t *, char *);
209
+
210
+sol_object_t *sol_get_stdin(sol_state_t *);
211
+sol_object_t *sol_get_stdout(sol_state_t *);
212
+sol_object_t *sol_get_stderr(sol_state_t *);
213
+
171 214
 void sol_ops_init(sol_ops_t *);
172 215
 
173 216
 // builtins.c
@@ -175,6 +218,8 @@ void sol_ops_init(sol_ops_t *);
175 218
 sol_object_t *sol_f_not_impl(sol_state_t *, sol_object_t *);
176 219
 sol_object_t *sol_f_no_op(sol_state_t *, sol_object_t *);
177 220
 sol_object_t *sol_f_default_cmp(sol_state_t *, sol_object_t *);
221
+sol_object_t *sol_f_default_tostring(sol_state_t *, sol_object_t *);
222
+sol_object_t *sol_f_default_repr(sol_state_t *, sol_object_t *);
178 223
 
179 224
 sol_object_t *sol_f_toint(sol_state_t *, sol_object_t *);
180 225
 sol_object_t *sol_f_tofloat(sol_state_t *, sol_object_t *);
@@ -203,6 +248,8 @@ sol_object_t *sol_f_iter_str(sol_state_t *, sol_object_t *);
203 248
 sol_object_t *sol_f_iter_list(sol_state_t *, sol_object_t *);
204 249
 sol_object_t *sol_f_iter_map(sol_state_t *, sol_object_t *);
205 250
 
251
+sol_object_t *sol_f_singlet_tostring(sol_state_t *, sol_object_t *);
252
+
206 253
 sol_object_t *sol_f_int_add(sol_state_t *, sol_object_t *);
207 254
 sol_object_t *sol_f_int_sub(sol_state_t *, sol_object_t *);
208 255
 sol_object_t *sol_f_int_mul(sol_state_t *, sol_object_t *);
@@ -239,6 +286,7 @@ sol_object_t *sol_f_str_index(sol_state_t *, sol_object_t *);
239 286
 sol_object_t *sol_f_str_toint(sol_state_t *, sol_object_t *);
240 287
 sol_object_t *sol_f_str_tofloat(sol_state_t *, sol_object_t *);
241 288
 sol_object_t *sol_f_str_tostring(sol_state_t *, sol_object_t *);
289
+sol_object_t *sol_f_str_repr(sol_state_t *, sol_object_t *);
242 290
 
243 291
 sol_object_t *sol_f_list_add(sol_state_t *, sol_object_t *);
244 292
 sol_object_t *sol_f_list_mul(sol_state_t *, sol_object_t *);
@@ -263,6 +311,8 @@ sol_object_t *sol_f_map_len(sol_state_t *, sol_object_t *);
263 311
 sol_object_t *sol_f_map_iter(sol_state_t *, sol_object_t *);
264 312
 sol_object_t *sol_f_map_tostring(sol_state_t *, sol_object_t *);
265 313
 
314
+sol_object_t *sol_f_mcell_tostring(sol_state_t *, sol_object_t *);
315
+
266 316
 sol_object_t *sol_f_func_call(sol_state_t *, sol_object_t *); // Defined in ast.c
267 317
 sol_object_t *sol_f_func_index(sol_state_t *, sol_object_t *);
268 318
 sol_object_t *sol_f_func_setindex(sol_state_t *, sol_object_t *);
@@ -278,17 +328,42 @@ sol_object_t *sol_f_astnode_tostring(sol_state_t *, sol_object_t *);
278 328
 
279 329
 sol_object_t *sol_f_buffer_index(sol_state_t *, sol_object_t *);
280 330
 sol_object_t *sol_f_buffer_tostring(sol_state_t *, sol_object_t *);
281
-sol_object_t *sol_f_buffer_free(sol_state_t *, sol_object_t *);
282 331
 
283
-sol_object_t *sol_f_buffer_new(sol_state_t *, sol_object_t *);
284 332
 sol_object_t *sol_f_buffer_get(sol_state_t *, sol_object_t *);
285 333
 sol_object_t *sol_f_buffer_set(sol_state_t *, sol_object_t *);
286 334
 sol_object_t *sol_f_buffer_address(sol_state_t *, sol_object_t *);
287 335
 sol_object_t *sol_f_buffer_size(sol_state_t *, sol_object_t *);
336
+
337
+sol_object_t *sol_f_buffer_new(sol_state_t *, sol_object_t *);
288 338
 sol_object_t *sol_f_buffer_fromstring(sol_state_t *, sol_object_t *);
289 339
 sol_object_t *sol_f_buffer_fromobject(sol_state_t *, sol_object_t *);
290 340
 sol_object_t *sol_f_buffer_fromaddress(sol_state_t *, sol_object_t *);
291 341
 
342
+sol_object_t *sol_f_dylib_index(sol_state_t *, sol_object_t *); 
343
+sol_object_t *sol_f_dylib_tostring(sol_state_t *, sol_object_t *);
344
+
345
+sol_object_t *sol_f_dylib_open(sol_state_t *, sol_object_t *);
346
+
347
+sol_object_t *sol_f_dysym_call(sol_state_t *, sol_object_t *);
348
+sol_object_t *sol_f_dysym_index(sol_state_t *, sol_object_t *);
349
+sol_object_t *sol_f_dysym_setindex(sol_state_t *, sol_object_t *);
350
+sol_object_t *sol_f_dysym_tostring(sol_state_t *, sol_object_t *);
351
+
352
+sol_object_t *sol_f_dysym_get(sol_state_t *, sol_object_t *);
353
+sol_object_t *sol_f_dysym_set(sol_state_t *, sol_object_t *);
354
+
355
+sol_object_t *sol_f_stream_blsh(sol_state_t *, sol_object_t *);
356
+sol_object_t *sol_f_stream_brsh(sol_state_t *, sol_object_t *);
357
+sol_object_t *sol_f_stream_index(sol_state_t *, sol_object_t *);
358
+sol_object_t *sol_f_stream_tostring(sol_state_t *, sol_object_t *);
359
+
360
+sol_object_t *sol_f_stream_write(sol_state_t *, sol_object_t *);
361
+sol_object_t *sol_f_stream_read(sol_state_t *, sol_object_t *);
362
+sol_object_t *sol_f_stream_seek(sol_state_t *, sol_object_t *);
363
+sol_object_t *sol_f_stream_tell(sol_state_t *, sol_object_t *);
364
+sol_object_t *sol_f_stream_flush(sol_state_t *, sol_object_t *);
365
+
366
+sol_object_t *sol_f_stream_open(sol_state_t *, sol_object_t *);
292 367
 
293 368
 // object.c
294 369
 
@@ -326,6 +401,8 @@ sol_object_t *sol_new_float(sol_state_t *, double);
326 401
 sol_object_t *sol_new_string(sol_state_t *, const char *);
327 402
 int sol_string_cmp(sol_state_t *, sol_object_t *, const char *);
328 403
 #define sol_string_eq(state, string, cstr) (sol_string_cmp((state), (string), (cstr))==0)
404
+sol_object_t *sol_string_concat(sol_state_t *, sol_object_t *, sol_object_t *);
405
+sol_object_t *sol_string_concat_cstr(sol_state_t *, sol_object_t *, char *);
329 406
 
330 407
 sol_object_t *sol_new_list(sol_state_t *);
331 408
 sol_object_t *sol_list_from_seq(sol_state_t *, dsl_seq *);
@@ -353,6 +430,7 @@ void sol_map_set_existing(sol_state_t *, sol_object_t *, sol_object_t *, sol_obj
353 430
 sol_object_t *sol_map_copy(sol_state_t *, sol_object_t *);
354 431
 void sol_map_merge(sol_state_t *, sol_object_t *, sol_object_t *);
355 432
 void sol_map_merge_existing(sol_state_t *, sol_object_t *, sol_object_t *);
433
+void sol_map_invert(sol_state_t *, sol_object_t *);
356 434
 
357 435
 // Defined in ast.h
358 436
 // sol_object_t *sol_new_func(sol_state_t *, identlist_node *, stmt_node *, char *);
@@ -364,14 +442,39 @@ sol_object_t *sol_new_cdata(sol_state_t *, void *, sol_ops_t *);
364 442
 
365 443
 sol_object_t *sol_new_buffer(sol_state_t *, void *, ssize_t, sol_owntype_t, sol_freefunc_t, sol_movefunc_t);
366 444
 
445
+sol_object_t *sol_new_dylib(sol_state_t *, void *);
446
+
447
+sol_object_t *sol_new_dysym(sol_state_t *, void *, dsl_seq *, sol_buftype_t);
448
+
449
+sol_object_t *sol_new_stream(sol_state_t *, FILE *, sol_modes_t);
450
+size_t sol_stream_printf(sol_state_t *, sol_object_t *, const char *, ...);
451
+size_t sol_stream_scanf(sol_state_t *, sol_object_t *, const char *, ...);
452
+size_t sol_stream_fread(sol_state_t *, sol_object_t *, char *, size_t, size_t);
453
+size_t sol_stream_fwrite(sol_state_t *, sol_object_t *, char *, size_t, size_t);
454
+char *sol_stream_fgets(sol_state_t *, sol_object_t *, char *, size_t);
455
+#define sol_printf(state, ...) sol_stream_printf(state, sol_get_stdout(state), __VA_ARGS__)
456
+#define sol_scanf(state, ...) sol_stream_scanf(state, sol_get_stdin(state, __VA_ARGS__)
457
+#define sol_fread(state, ...) sol_stream_fread(state, sol_get_stdin(state), __VA_ARGS__)
458
+#define sol_fwrite(state, ...) sol_stream_fwrite(state, sol_get_stdout(state), __VA_ARGS__)
459
+int sol_stream_feof(sol_state_t *, sol_object_t *);
460
+int sol_stream_ferror(sol_state_t *, sol_object_t *);
461
+#define sol_stream_ready(state, stream) (!(sol_stream_feof((state), (stream)) || sol_stream_ferror((state), (stream))))
462
+int sol_stream_fseek(sol_state_t *, sol_object_t *, long, int);
463
+long sol_stream_ftell(sol_state_t *, sol_object_t *);
464
+int sol_stream_fflush(sol_state_t *, sol_object_t *);
465
+
367 466
 sol_object_t *sol_cast_int(sol_state_t *, sol_object_t *);
368 467
 sol_object_t *sol_cast_float(sol_state_t *, sol_object_t *);
369 468
 sol_object_t *sol_cast_string(sol_state_t *, sol_object_t *);
469
+sol_object_t *sol_cast_repr(sol_state_t *, sol_object_t *);
370 470
 
371 471
 sol_object_t *sol_f_str_free(sol_state_t *, sol_object_t *);
372 472
 sol_object_t *sol_f_list_free(sol_state_t *, sol_object_t *);
373 473
 sol_object_t *sol_f_map_free(sol_state_t *, sol_object_t *);
374 474
 sol_object_t *sol_f_mcell_free(sol_state_t *, sol_object_t *);
475
+sol_object_t *sol_f_buffer_free(sol_state_t *, sol_object_t *);
476
+sol_object_t *sol_f_dylib_free(sol_state_t *, sol_object_t *);
477
+sol_object_t *sol_f_stream_free(sol_state_t *, sol_object_t *);
375 478
 
376 479
 int sol_validate_list(sol_state_t *, sol_object_t *);
377 480
 int sol_validate_map(sol_state_t *, sol_object_t *);

+ 268
- 98
state.c View File

@@ -1,8 +1,10 @@
1 1
 #include <stdint.h>
2
+#include <stdio.h>
2 3
 #include "ast.h"
3 4
 
4 5
 int sol_state_init(sol_state_t *state) {
5
-	sol_object_t *globals, *debug, *iter, *ast, *buffer, *btype, *bsize;
6
+	sol_object_t *globals, *mod, *meths;
7
+	sol_object_t *btype, *bsize, *bobj;
6 8
 
7 9
 	state->None = NULL;
8 10
 	state->OutOfMemory = NULL;
@@ -22,7 +24,8 @@ int sol_state_init(sol_state_t *state) {
22 24
 	//Initialize all of the builtin operations
23 25
 	//(these ones are technically already pointed to by None/OOM)
24 26
 	sol_ops_init(&(state->NullOps));
25
-
27
+	
28
+	state->SingletOps = state->NullOps;
26 29
 	state->IntOps = state->NullOps;
27 30
 	state->FloatOps = state->NullOps;
28 31
 	state->StringOps = state->NullOps;
@@ -33,7 +36,14 @@ int sol_state_init(sol_state_t *state) {
33 36
 	state->CFuncOps = state->NullOps;
34 37
 	state->ASTNodeOps = state->NullOps;
35 38
 	state->BufferOps = state->NullOps;
36
-
39
+	state->DyLibOps = state->NullOps;
40
+	state->DySymOps = state->NullOps;
41
+	state->StreamOps = state->NullOps;
42
+	
43
+	state->SingletOps.tname = "singlet";
44
+	state->SingletOps.tostring = sol_f_singlet_tostring;
45
+	
46
+	state->IntOps.tname = "int";
37 47
 	state->IntOps.add = sol_f_int_add;
38 48
 	state->IntOps.sub = sol_f_int_sub;
39 49
 	state->IntOps.mul = sol_f_int_mul;
@@ -49,7 +59,8 @@ int sol_state_init(sol_state_t *state) {
49 59
 	state->IntOps.toint = sol_f_int_toint;
50 60
 	state->IntOps.tofloat = sol_f_int_tofloat;
51 61
 	state->IntOps.tostring = sol_f_int_tostring;
52
-
62
+	
63
+	state->FloatOps.tname = "float";
53 64
 	state->FloatOps.add = sol_f_float_add;
54 65
 	state->FloatOps.sub = sol_f_float_sub;
55 66
 	state->FloatOps.mul = sol_f_float_mul;
@@ -58,7 +69,8 @@ int sol_state_init(sol_state_t *state) {
58 69
 	state->FloatOps.toint = sol_f_float_toint;
59 70
 	state->FloatOps.tofloat = sol_f_float_tofloat;
60 71
 	state->FloatOps.tostring = sol_f_float_tostring;
61
-
72
+	
73
+	state->StringOps.tname = "string";
62 74
 	state->StringOps.add = sol_f_str_add;
63 75
 	state->StringOps.mul = sol_f_str_mul;
64 76
 	state->StringOps.cmp = sol_f_str_cmp;
@@ -68,8 +80,10 @@ int sol_state_init(sol_state_t *state) {
68 80
 	state->StringOps.toint = sol_f_str_toint;
69 81
 	state->StringOps.tofloat = sol_f_str_tofloat;
70 82
 	state->StringOps.tostring = sol_f_str_tostring;
83
+	state->StringOps.repr = sol_f_str_repr;
71 84
 	state->StringOps.free = sol_f_str_free;
72
-
85
+	
86
+	state->ListOps.tname = "list";
73 87
 	state->ListOps.add = sol_f_list_add;
74 88
 	state->ListOps.mul = sol_f_list_mul;
75 89
 	state->ListOps.call = sol_f_not_impl;
@@ -79,7 +93,8 @@ int sol_state_init(sol_state_t *state) {
79 93
 	state->ListOps.iter = sol_f_list_iter;
80 94
 	state->ListOps.tostring = sol_f_list_tostring;
81 95
 	state->ListOps.free = sol_f_list_free;
82
-
96
+	
97
+	state->MapOps.tname = "map";
83 98
 	state->MapOps.add = sol_f_map_add;
84 99
 	state->MapOps.call = sol_f_map_call;
85 100
 	state->MapOps.index = sol_f_map_index;
@@ -88,27 +103,50 @@ int sol_state_init(sol_state_t *state) {
88 103
 	state->MapOps.iter = sol_f_map_iter;
89 104
 	state->MapOps.tostring = sol_f_map_tostring;
90 105
 	state->MapOps.free = sol_f_map_free;
91
-
92
-	state->MCellOps = state->MapOps;
106
+	
107
+	state->MCellOps.tname = "mcell";
108
+	state->MCellOps.tostring = sol_f_mcell_tostring;
93 109
 	state->MCellOps.free = sol_f_mcell_free;
94
-
110
+	
111
+	state->FuncOps.tname = "function";
95 112
 	state->FuncOps.call = sol_f_func_call;
96 113
 	state->FuncOps.index = sol_f_func_index;
97 114
 	state->FuncOps.setindex = sol_f_func_setindex;
98 115
 	state->FuncOps.tostring = sol_f_func_tostring;
99
-
116
+	
117
+	state->CFuncOps.tname = "cfunction";
100 118
 	state->CFuncOps.call = sol_f_cfunc_call;
101 119
 	state->CFuncOps.tostring = sol_f_cfunc_tostring;
102 120
 	
121
+	state->ASTNodeOps.tname = "astnode";
103 122
 	state->ASTNodeOps.call = sol_f_astnode_call;
104 123
 	state->ASTNodeOps.index = sol_f_astnode_index;
105 124
 	state->ASTNodeOps.setindex = sol_f_astnode_setindex;
106 125
 	state->ASTNodeOps.tostring = sol_f_astnode_tostring;
107 126
 	
127
+	state->BufferOps.tname = "buffer";
108 128
 	state->BufferOps.index = sol_f_buffer_index;
109 129
 	state->BufferOps.tostring = sol_f_buffer_tostring;
110 130
 	state->BufferOps.free = sol_f_buffer_free;
111 131
 	
132
+	state->DyLibOps.tname = "dylib";
133
+	state->DyLibOps.index = sol_f_dylib_index;
134
+	state->DyLibOps.free = sol_f_dylib_free;
135
+	state->DyLibOps.tostring = sol_f_dylib_tostring;
136
+	
137
+	state->DySymOps.tname = "dysym";
138
+	state->DySymOps.call = sol_f_dysym_call;
139
+	state->DySymOps.index = sol_f_dysym_index;
140
+	state->DySymOps.setindex = sol_f_dysym_setindex;
141
+	state->DySymOps.tostring = sol_f_dysym_tostring;
142
+	
143
+	state->StreamOps.tname = "stream";
144
+	state->StreamOps.blsh = sol_f_stream_blsh;
145
+	state->StreamOps.brsh = sol_f_stream_brsh;
146
+	state->StreamOps.index = sol_f_stream_index;
147
+	state->StreamOps.free = sol_f_stream_free;
148
+	state->StreamOps.tostring = sol_f_stream_tostring;
149
+	
112 150
 	state->obfuncs.copy = (dsl_copier) sol_obj_acquire;
113 151
 	state->obfuncs.destr = (dsl_destructor) sol_obj_free;
114 152
 
@@ -116,14 +154,11 @@ int sol_state_init(sol_state_t *state) {
116 154
 	state->scopes = sol_new_list(state);
117 155
 	if(sol_has_error(state)) goto cleanup;
118 156
 	globals = sol_new_map(state);
119
-	debug = sol_new_map(state);
120
-	iter = sol_new_map(state);
121
-	ast = sol_new_map(state);
122
-	btype = sol_new_map(state);
123
-	bsize = sol_new_map(state);
124
-	buffer = sol_new_map(state);
157
+	state->modules = sol_new_map(state);
158
+	state->methods = sol_new_map(state);
125 159
 	if(sol_has_error(state)) goto cleanup;
126 160
 	sol_list_insert(state, state->scopes, 0, globals);
161
+	sol_obj_free(globals);
127 162
 	if(sol_has_error(state)) goto cleanup;
128 163
 	// I'm going to buffer all of these together because I can.
129 164
 	sol_map_set_name(state, globals, "OutOfMemory", state->OutOfMemory);
@@ -143,65 +178,71 @@ int sol_state_init(sol_state_t *state) {
143 178
 	sol_map_set_name(state, globals, "eval", sol_new_cfunc(state, sol_f_eval));
144 179
 	sol_map_set_name(state, globals, "execfile", sol_new_cfunc(state, sol_f_execfile));
145 180
 	sol_map_set_name(state, globals, "parse", sol_new_cfunc(state, sol_f_parse));
146
-
147
-	sol_map_set_name(state, debug, "getref", sol_new_cfunc(state, sol_f_debug_getref));
148
-	sol_map_set_name(state, debug, "setref", sol_new_cfunc(state, sol_f_debug_setref));
149
-	sol_map_set_name(state, debug, "closure", sol_new_cfunc(state, sol_f_debug_closure));
150
-	sol_map_set_name(state, debug, "globals", sol_new_cfunc(state, sol_f_debug_globals));
151
-	sol_map_set_name(state, debug, "locals", sol_new_cfunc(state, sol_f_debug_locals));
152
-	sol_map_set_name(state, debug, "scopes", sol_new_cfunc(state, sol_f_debug_scopes));
153
-	sol_map_set_name(state, globals, "debug", debug);
154
-	sol_obj_free(debug);
155
-
156
-	sol_map_set_name(state, iter, "str", sol_new_cfunc(state, sol_f_iter_str));
157
-	sol_map_set_name(state, iter, "list", sol_new_cfunc(state, sol_f_iter_list));
158
-	sol_map_set_name(state, iter, "map", sol_new_cfunc(state, sol_f_iter_map));
159
-	sol_map_set_name(state, globals, "iter", iter);
160
-	sol_obj_free(iter);
161 181
 	
162
-	sol_map_set_name(state, ast, "ST_EXPR", sol_new_int(state, ST_EXPR));
163
-	sol_map_set_name(state, ast, "ST_IFELSE", sol_new_int(state, ST_IFELSE));
164
-	sol_map_set_name(state, ast, "ST_LOOP", sol_new_int(state, ST_LOOP));
165
-	sol_map_set_name(state, ast, "ST_ITER", sol_new_int(state, ST_ITER));
166
-	sol_map_set_name(state, ast, "ST_LIST", sol_new_int(state, ST_LIST));
167
-	sol_map_set_name(state, ast, "ST_RET", sol_new_int(state, ST_RET));
168
-	sol_map_set_name(state, ast, "ST_CONT", sol_new_int(state, ST_CONT));
169
-	sol_map_set_name(state, ast, "ST_BREAK", sol_new_int(state, ST_BREAK));
170
-	sol_map_set_name(state, ast, "EX_LIT", sol_new_int(state, EX_LIT));
171
-	sol_map_set_name(state, ast, "EX_LISTGEN", sol_new_int(state, EX_LIT));
172
-	sol_map_set_name(state, ast, "EX_MAPGEN", sol_new_int(state, EX_LIT));
173
-	sol_map_set_name(state, ast, "EX_BINOP", sol_new_int(state, EX_LIT));
174
-	sol_map_set_name(state, ast, "EX_UNOP", sol_new_int(state, EX_LIT));
175
-	sol_map_set_name(state, ast, "EX_INDEX", sol_new_int(state, EX_LIT));
176
-	sol_map_set_name(state, ast, "EX_SETINDEX", sol_new_int(state, EX_LIT));
177
-	sol_map_set_name(state, ast, "EX_ASSIGN", sol_new_int(state, EX_LIT));
178
-	sol_map_set_name(state, ast, "EX_REF", sol_new_int(state, EX_LIT));
179
-	sol_map_set_name(state, ast, "EX_CALL", sol_new_int(state, EX_LIT));
180
-	sol_map_set_name(state, ast, "EX_FUNCDECL", sol_new_int(state, EX_LIT));
181
-	sol_map_set_name(state, ast, "OP_ADD", sol_new_int(state, OP_ADD));
182
-	sol_map_set_name(state, ast, "OP_SUB", sol_new_int(state, OP_SUB));
183
-	sol_map_set_name(state, ast, "OP_MUL", sol_new_int(state, OP_MUL));
184
-	sol_map_set_name(state, ast, "OP_DIV", sol_new_int(state, OP_DIV));
185
-	sol_map_set_name(state, ast, "OP_MOD", sol_new_int(state, OP_MOD));
186
-	sol_map_set_name(state, ast, "OP_POW", sol_new_int(state, OP_POW));
187
-	sol_map_set_name(state, ast, "OP_BAND", sol_new_int(state, OP_BAND));
188
-	sol_map_set_name(state, ast, "OP_BOR", sol_new_int(state, OP_BOR));
189
-	sol_map_set_name(state, ast, "OP_BXOR", sol_new_int(state, OP_BXOR));
190
-	sol_map_set_name(state, ast, "OP_LAND", sol_new_int(state, OP_LAND));
191
-	sol_map_set_name(state, ast, "OP_LOR", sol_new_int(state, OP_LOR));
192
-	sol_map_set_name(state, ast, "OP_EQUAL", sol_new_int(state, OP_EQUAL));
193
-	sol_map_set_name(state, ast, "OP_LESS", sol_new_int(state, OP_LESS));
194
-	sol_map_set_name(state, ast, "OP_GREATER", sol_new_int(state, OP_GREATER));
195
-	sol_map_set_name(state, ast, "OP_LESSEQ", sol_new_int(state, OP_LESSEQ));
196
-	sol_map_set_name(state, ast, "OP_GREATEREQ", sol_new_int(state, OP_GREATEREQ));
197
-	sol_map_set_name(state, ast, "OP_LSHIFT", sol_new_int(state, OP_LSHIFT));
198
-	sol_map_set_name(state, ast, "OP_RSHIFT", sol_new_int(state, OP_RSHIFT));
199
-	sol_map_set_name(state, ast, "OP_NEG", sol_new_int(state, OP_NEG));
200
-	sol_map_set_name(state, ast, "OP_BNOT", sol_new_int(state, OP_BNOT));
201
-	sol_map_set_name(state, ast, "OP_LNOT", sol_new_int(state, OP_LNOT));
202
-	sol_map_set_name(state, ast, "OP_LEN", sol_new_int(state, OP_LEN));
203
-	sol_map_set_name(state, globals, "ast", ast);
182
+	mod = sol_new_map(state);
183
+	sol_map_set_name(state, mod, "getref", sol_new_cfunc(state, sol_f_debug_getref));
184
+	sol_map_set_name(state, mod, "setref", sol_new_cfunc(state, sol_f_debug_setref));
185
+	sol_map_set_name(state, mod, "closure", sol_new_cfunc(state, sol_f_debug_closure));
186
+	sol_map_set_name(state, mod, "globals", sol_new_cfunc(state, sol_f_debug_globals));
187
+	sol_map_set_name(state, mod, "locals", sol_new_cfunc(state, sol_f_debug_locals));
188
+	sol_map_set_name(state, mod, "scopes", sol_new_cfunc(state, sol_f_debug_scopes));
189
+	sol_register_module_name(state, "debug", mod);
190
+	sol_obj_free(mod);
191
+	
192
+	mod = sol_new_map(state);
193
+	sol_map_set_name(state, mod, "str", sol_new_cfunc(state, sol_f_iter_str));
194
+	sol_map_set_name(state, mod, "list", sol_new_cfunc(state, sol_f_iter_list));
195
+	sol_map_set_name(state, mod, "map", sol_new_cfunc(state, sol_f_iter_map));
196
+	sol_register_module_name(state, "iter", mod);
197
+	sol_obj_free(mod);
204 198
 	
199
+	mod = sol_new_map(state);
200
+	sol_map_set_name(state, mod, "ST_EXPR", sol_new_int(state, ST_EXPR));
201
+	sol_map_set_name(state, mod, "ST_IFELSE", sol_new_int(state, ST_IFELSE));
202
+	sol_map_set_name(state, mod, "ST_LOOP", sol_new_int(state, ST_LOOP));
203
+	sol_map_set_name(state, mod, "ST_ITER", sol_new_int(state, ST_ITER));
204
+	sol_map_set_name(state, mod, "ST_LIST", sol_new_int(state, ST_LIST));
205
+	sol_map_set_name(state, mod, "ST_RET", sol_new_int(state, ST_RET));
206
+	sol_map_set_name(state, mod, "ST_CONT", sol_new_int(state, ST_CONT));
207
+	sol_map_set_name(state, mod, "ST_BREAK", sol_new_int(state, ST_BREAK));
208
+	sol_map_set_name(state, mod, "EX_LIT", sol_new_int(state, EX_LIT));
209
+	sol_map_set_name(state, mod, "EX_LISTGEN", sol_new_int(state, EX_LIT));
210
+	sol_map_set_name(state, mod, "EX_MAPGEN", sol_new_int(state, EX_LIT));
211
+	sol_map_set_name(state, mod, "EX_BINOP", sol_new_int(state, EX_LIT));
212
+	sol_map_set_name(state, mod, "EX_UNOP", sol_new_int(state, EX_LIT));
213
+	sol_map_set_name(state, mod, "EX_INDEX", sol_new_int(state, EX_LIT));
214
+	sol_map_set_name(state, mod, "EX_SETINDEX", sol_new_int(state, EX_LIT));
215
+	sol_map_set_name(state, mod, "EX_ASSIGN", sol_new_int(state, EX_LIT));
216
+	sol_map_set_name(state, mod, "EX_REF", sol_new_int(state, EX_LIT));
217
+	sol_map_set_name(state, mod, "EX_CALL", sol_new_int(state, EX_LIT));
218
+	sol_map_set_name(state, mod, "EX_FUNCDECL", sol_new_int(state, EX_LIT));
219
+	sol_map_set_name(state, mod, "OP_ADD", sol_new_int(state, OP_ADD));
220
+	sol_map_set_name(state, mod, "OP_SUB", sol_new_int(state, OP_SUB));
221
+	sol_map_set_name(state, mod, "OP_MUL", sol_new_int(state, OP_MUL));
222
+	sol_map_set_name(state, mod, "OP_DIV", sol_new_int(state, OP_DIV));
223
+	sol_map_set_name(state, mod, "OP_MOD", sol_new_int(state, OP_MOD));
224
+	sol_map_set_name(state, mod, "OP_POW", sol_new_int(state, OP_POW));
225
+	sol_map_set_name(state, mod, "OP_BAND", sol_new_int(state, OP_BAND));
226
+	sol_map_set_name(state, mod, "OP_BOR", sol_new_int(state, OP_BOR));
227
+	sol_map_set_name(state, mod, "OP_BXOR", sol_new_int(state, OP_BXOR));
228
+	sol_map_set_name(state, mod, "OP_LAND", sol_new_int(state, OP_LAND));
229
+	sol_map_set_name(state, mod, "OP_LOR", sol_new_int(state, OP_LOR));
230
+	sol_map_set_name(state, mod, "OP_EQUAL", sol_new_int(state, OP_EQUAL));
231
+	sol_map_set_name(state, mod, "OP_LESS", sol_new_int(state, OP_LESS));
232
+	sol_map_set_name(state, mod, "OP_GREATER", sol_new_int(state, OP_GREATER));
233
+	sol_map_set_name(state, mod, "OP_LESSEQ", sol_new_int(state, OP_LESSEQ));
234
+	sol_map_set_name(state, mod, "OP_GREATEREQ", sol_new_int(state, OP_GREATEREQ));
235
+	sol_map_set_name(state, mod, "OP_LSHIFT", sol_new_int(state, OP_LSHIFT));
236
+	sol_map_set_name(state, mod, "OP_RSHIFT", sol_new_int(state, OP_RSHIFT));
237
+	sol_map_set_name(state, mod, "OP_NEG", sol_new_int(state, OP_NEG));
238
+	sol_map_set_name(state, mod, "OP_BNOT", sol_new_int(state, OP_BNOT));
239
+	sol_map_set_name(state, mod, "OP_LNOT", sol_new_int(state, OP_LNOT));
240
+	sol_map_set_name(state, mod, "OP_LEN", sol_new_int(state, OP_LEN));
241
+	sol_map_invert(state, mod);
242
+	sol_register_module_name(state, "ast", mod);
243
+	
244
+	btype = sol_new_map(state);
245
+	sol_map_set_name(state, btype, "none", sol_new_int(state, BUF_NONE));
205 246
 	sol_map_set_name(state, btype, "uint8", sol_new_int(state, BUF_UINT8));
206 247
 	sol_map_set_name(state, btype, "uint16", sol_new_int(state, BUF_UINT16));
207 248
 	sol_map_set_name(state, btype, "uint32", sol_new_int(state, BUF_UINT32));
@@ -220,7 +261,9 @@ int sol_state_init(sol_state_t *state) {
220 261
 	sol_map_set_name(state, btype, "double", sol_new_int(state, BUF_DOUBLE));
221 262
 	sol_map_set_name(state, btype, "cstr", sol_new_int(state, BUF_CSTR));
222 263
 	sol_map_set_name(state, btype, "ptr", sol_new_int(state, BUF_PTR));
264
+	sol_map_invert(state, btype);
223 265
 	
266
+	bsize = sol_new_map(state);
224 267
 	sol_map_set_name(state, bsize, "uint8", sol_new_int(state, sizeof(uint8_t)));
225 268
 	sol_map_set_name(state, bsize, "uint16", sol_new_int(state, sizeof(uint16_t)));
226 269
 	sol_map_set_name(state, bsize, "uint32", sol_new_int(state, sizeof(uint32_t)));
@@ -239,30 +282,84 @@ int sol_state_init(sol_state_t *state) {
239 282
 	sol_map_set_name(state, bsize, "double", sol_new_int(state, sizeof(double)));
240 283
 	sol_map_set_name(state, bsize, "cstr", sol_new_int(state, sizeof(char *)));
241 284
 	sol_map_set_name(state, bsize, "ptr", sol_new_int(state, sizeof(void *)));
242
-
243
-	state->ListFuncs = sol_new_map(state);
244
-	sol_map_set_name(state, state->ListFuncs, "copy", sol_new_cfunc(state, sol_f_list_copy));
245
-	sol_map_set_name(state, state->ListFuncs, "insert", sol_new_cfunc(state, sol_f_list_insert));
246
-	sol_map_set_name(state, state->ListFuncs, "remove", sol_new_cfunc(state, sol_f_list_remove));
247
-	sol_map_set_name(state, state->ListFuncs, "truncate", sol_new_cfunc(state, sol_f_list_truncate));
248
-	sol_map_set_name(state, state->ListFuncs, "map", sol_new_cfunc(state, sol_f_list_map));
249
-	sol_map_set_name(state, state->ListFuncs, "filter", sol_new_cfunc(state, sol_f_list_filter));
250
-	sol_map_set_name(state, globals, "list", state->ListFuncs);
251 285
 	
252
-	state->BufferFuncs = sol_new_map(state);
253
-	sol_map_set_name(state, state->BufferFuncs, "new", sol_new_cfunc(state, sol_f_buffer_new));
254
-	sol_map_set_name(state, state->BufferFuncs, "get", sol_new_cfunc(state, sol_f_buffer_get));
255
-	sol_map_set_name(state, state->BufferFuncs, "set", sol_new_cfunc(state, sol_f_buffer_set));
256
-	sol_map_set_name(state, state->BufferFuncs, "address", sol_new_cfunc(state, sol_f_buffer_address));
257
-	sol_map_set_name(state, state->BufferFuncs, "size", sol_new_cfunc(state, sol_f_buffer_size));
258
-	sol_map_set_name(state, state->BufferFuncs, "fromstring", sol_new_cfunc(state, sol_f_buffer_fromstring));
259
-	sol_map_set_name(state, state->BufferFuncs, "fromobject", sol_new_cfunc(state, sol_f_buffer_fromobject));
260
-	sol_map_set_name(state, state->BufferFuncs, "fromaddress", sol_new_cfunc(state, sol_f_buffer_fromaddress));
261
-	sol_map_set_name(state, state->BufferFuncs, "type", btype);
262
-	sol_map_set_name(state, state->BufferFuncs, "size", bsize);
263
-	sol_map_set_name(state, globals, "buffer", state->BufferFuncs);
286
+	bobj = sol_new_map(state);
287
+	sol_map_set_name(state, bobj, "SOL_SINGLET", sol_new_int(state, SOL_SINGLET));
288
+	sol_map_set_name(state, bobj, "SOL_INTEGER", sol_new_int(state, SOL_INTEGER));
289
+	sol_map_set_name(state, bobj, "SOL_FLOAT", sol_new_int(state, SOL_FLOAT));
290
+	sol_map_set_name(state, bobj, "SOL_STRING", sol_new_int(state, SOL_STRING));
291
+	sol_map_set_name(state, bobj, "SOL_LIST", sol_new_int(state, SOL_LIST));
292
+	sol_map_set_name(state, bobj, "SOL_MAP", sol_new_int(state, SOL_MAP));
293
+	sol_map_set_name(state, bobj, "SOL_MCELL", sol_new_int(state, SOL_MCELL));
294
+	sol_map_set_name(state, bobj, "SOL_FUNCTION", sol_new_int(state, SOL_FUNCTION));
295
+	sol_map_set_name(state, bobj, "SOL_CFUNCTION", sol_new_int(state, SOL_CFUNCTION));
296
+	sol_map_set_name(state, bobj, "SOL_STMT", sol_new_int(state, SOL_STMT));
297
+	sol_map_set_name(state, bobj, "SOL_EXPR", sol_new_int(state, SOL_EXPR));
298
+	sol_map_set_name(state, bobj, "SOL_BUFFER", sol_new_int(state, SOL_BUFFER));
299
+	sol_map_set_name(state, bobj, "SOL_DYLIB", sol_new_int(state, SOL_DYLIB));
300
+	sol_map_set_name(state, bobj, "SOL_DYSYM", sol_new_int(state, SOL_DYSYM));
301
+	sol_map_set_name(state, bobj, "SOL_STREAM", sol_new_int(state, SOL_STREAM));
302
+	sol_map_set_name(state, bobj, "SOL_CDATA", sol_new_int(state, SOL_CDATA));
303
+	sol_map_invert(state, bobj);
264 304
 	
265
-	sol_obj_free(globals);
305
+	mod = sol_new_map(state);
306
+	sol_map_set_name(state, mod, "new", sol_new_cfunc(state, sol_f_buffer_new));
307
+	sol_map_set_name(state, mod, "fromstring", sol_new_cfunc(state, sol_f_buffer_fromstring));
308
+	sol_map_set_name(state, mod, "fromobject", sol_new_cfunc(state, sol_f_buffer_fromobject));
309
+	sol_map_set_name(state, mod, "fromaddress", sol_new_cfunc(state, sol_f_buffer_fromaddress));
310
+	sol_map_set_name(state, mod, "type", btype);
311
+	sol_map_set_name(state, mod, "sizeof", bsize);
312
+	sol_map_set_name(state, mod, "objtype", bobj);
313
+	sol_register_module_name(state, "buffer", mod);
314
+	sol_obj_free(mod);
315
+	sol_obj_free(bobj);
316
+	sol_obj_free(bsize);
317
+	sol_obj_free(btype);
318
+	
319
+	mod = sol_new_map(state);
320
+	sol_map_set_name(state, mod, "MODE_READ", sol_new_int(state, MODE_READ));
321
+	sol_map_set_name(state, mod, "MODE_WRITE", sol_new_int(state, MODE_WRITE));
322
+	sol_map_set_name(state, mod, "MODE_APPEND", sol_new_int(state, MODE_APPEND));
323
+	sol_map_set_name(state, mod, "MODE_TRUNCATE", sol_new_int(state, MODE_TRUNCATE));
324
+	sol_map_set_name(state, mod, "MODE_BINARY", sol_new_int(state, MODE_BINARY));
325
+	sol_map_set_name(state, mod, "SEEK_SET", sol_new_int(state, SEEK_SET));
326
+	sol_map_set_name(state, mod, "SEEK_CUR", sol_new_int(state, SEEK_CUR));
327
+	sol_map_set_name(state, mod, "SEEK_END", sol_new_int(state, SEEK_END));
328
+	sol_map_set_name(state, mod, "ALL", sol_new_string(state, "ALL"));
329
+	sol_map_set_name(state, mod, "LINE", sol_new_string(state, "LINE"));
330
+	sol_map_set_name(state, mod, "stdin", sol_new_stream(state, stdin, MODE_READ));
331
+	sol_map_set_name(state, mod, "stdout", sol_new_stream(state, stdout, MODE_WRITE));
332
+	sol_map_set_name(state, mod, "stderr", sol_new_stream(state, stderr, MODE_WRITE));
333
+	sol_map_set_name(state, mod, "open", sol_new_cfunc(state, sol_f_stream_open));
334
+	sol_register_module_name(state, "io", mod);
335
+	sol_obj_free(mod);
336
+	
337
+	meths = sol_new_map(state);
338
+	sol_map_set_name(state, meths, "get", sol_new_cfunc(state, sol_f_buffer_get));
339
+	sol_map_set_name(state, meths, "set", sol_new_cfunc(state, sol_f_buffer_set));
340
+	sol_map_set_name(state, meths, "address", sol_new_cfunc(state, sol_f_buffer_address));
341
+	sol_map_set_name(state, meths, "size", sol_new_cfunc(state, sol_f_buffer_size));
342
+	sol_register_methods_name(state, "buffer", meths);
343
+	sol_obj_free(meths);
344
+
345
+	meths = sol_new_map(state);
346
+	sol_map_set_name(state, meths, "copy", sol_new_cfunc(state, sol_f_list_copy));
347
+	sol_map_set_name(state, meths, "insert", sol_new_cfunc(state, sol_f_list_insert));
348
+	sol_map_set_name(state, meths, "remove", sol_new_cfunc(state, sol_f_list_remove));
349
+	sol_map_set_name(state, meths, "truncate", sol_new_cfunc(state, sol_f_list_truncate));
350
+	sol_map_set_name(state, meths, "map", sol_new_cfunc(state, sol_f_list_map));
351
+	sol_map_set_name(state, meths, "filter", sol_new_cfunc(state, sol_f_list_filter));
352
+	sol_register_methods_name(state, "list", meths);
353
+	sol_obj_free(meths);
354
+	
355
+	meths = sol_new_map(state);
356
+	sol_map_set_name(state, meths, "read", sol_new_cfunc(state, sol_f_stream_read));
357
+	sol_map_set_name(state, meths, "write", sol_new_cfunc(state, sol_f_stream_write));
358
+	sol_map_set_name(state, meths, "seek", sol_new_cfunc(state, sol_f_stream_seek));
359
+	sol_map_set_name(state, meths, "tell", sol_new_cfunc(state, sol_f_stream_tell));
360
+	sol_map_set_name(state, meths, "flush", sol_new_cfunc(state, sol_f_stream_flush));
361
+	sol_register_methods_name(state, "stream", meths);
362
+	sol_obj_free(meths);
266 363
 	
267 364
 	if(sol_has_error(state)) goto cleanup;
268 365
 
@@ -283,7 +380,8 @@ void sol_state_cleanup(sol_state_t *state) {
283 380
 	sol_obj_free(state->OutOfMemory);
284 381
 	sol_obj_free(state->StopIteration);
285 382
 	sol_obj_free(state->ret);
286
-	sol_obj_free(state->ListFuncs);
383
+	sol_obj_free(state->modules);
384
+	sol_obj_free(state->methods);
287 385
 }
288 386
 
289 387
 sol_object_t *sol_state_resolve(sol_state_t *state, sol_object_t *key) {
@@ -305,6 +403,11 @@ sol_object_t *sol_state_resolve(sol_state_t *state, sol_object_t *key) {
305 403
 	}
306 404
 	dsl_free_seq_iter(iter);
307 405
 	sol_obj_free(args);
406
+	
407
+	temp = sol_get_module(state, key);
408
+	if(!sol_is_none(state, temp)) {
409
+		return temp;
410
+	}
308 411
 
309 412
 	return sol_incref(state->None);
310 413
 }
@@ -413,7 +516,73 @@ void sol_clear_error(sol_state_t *state) {
413 516
 	sol_obj_free(olderr);
414 517
 }
415 518
 
519
+void sol_register_module(sol_state_t *state, sol_object_t *key, sol_object_t *val) {
520
+	sol_map_set(state, state->modules, key, val);
521
+}
522
+
523
+void sol_register_module_name(sol_state_t *state, char *name, sol_object_t *val) {
524
+	sol_map_set_name(state, state->modules, name, val);
525
+}
526
+
527
+sol_object_t *sol_get_module(sol_state_t *state, sol_object_t *key) {
528
+	return sol_map_get(state, state->modules, key);
529
+}
530
+
531
+sol_object_t *sol_get_module_name(sol_state_t *state, char *name) {
532
+	return sol_map_get_name(state, state->modules, name);
533
+}
534
+
535
+void sol_register_methods(sol_state_t *state, sol_object_t *key, sol_object_t *val) {
536
+	sol_map_set(state, state->methods, key, val);
537
+}
538
+
539
+void sol_register_methods_name(sol_state_t *state, char *name, sol_object_t *val) {
540
+	sol_map_set_name(state, state->methods, name, val);
541
+}
542
+
543
+sol_object_t *sol_get_methods(sol_state_t *state, sol_object_t *key) {
544
+	return sol_map_get(state, state->methods, key);
545
+}
546
+
547
+sol_object_t *sol_get_methods_name(sol_state_t *state, char *name) {
548
+	return sol_map_get_name(state, state->methods, name);
549
+}
550
+
551
+sol_object_t *sol_get_stdin(sol_state_t *state) {
552
+	sol_object_t *io = sol_state_resolve_name(state, "io");
553
+	sol_object_t *res = sol_map_get_name(state, io, "stdin");
554
+	sol_obj_free(io);
555
+	if(sol_is_none(state, res)) {
556
+		printf("WARNING: No io.stdin, returning a new ref\n");
557
+		return sol_new_stream(state, stdin, MODE_READ);
558
+	}
559
+	return res;
560
+}
561
+
562
+sol_object_t *sol_get_stdout(sol_state_t *state) {
563
+	sol_object_t *io = sol_state_resolve_name(state, "io");
564
+	sol_object_t *res = sol_map_get_name(state, io, "stdout");
565
+	sol_obj_free(io);
566
+	if(sol_is_none(state, res)) {
567
+		printf("WARNING: No io.stdout, returning a new ref\n");
568
+		return sol_new_stream(state, stdout, MODE_WRITE);
569
+	}
570
+	return res;
571
+}
572
+
573
+sol_object_t *sol_get_stderr(sol_state_t *state) {
574
+	sol_object_t *io = sol_state_resolve_name(state, "io");
575
+	sol_object_t *res = sol_map_get_name(state, io, "stderr");
576
+	sol_obj_free(io);
577
+	if(sol_is_none(state, res)) {
578
+		printf("WARNING: No io.stderr, returning a new ref\n");
579
+		return sol_new_stream(state, stderr, MODE_WRITE);
580
+	}
581
+	return res;
582
+}
583
+
416 584
 void sol_ops_init(sol_ops_t *ops) {
585
+	ops->tname = "unknown";
417 586
     ops->add = sol_f_not_impl;
418 587
 	ops->sub = sol_f_not_impl;
419 588
 	ops->mul = sol_f_not_impl;
@@ -433,7 +602,8 @@ void sol_ops_init(sol_ops_t *ops) {
433 602
 	ops->iter = sol_f_not_impl;
434 603
 	ops->toint = sol_f_not_impl;
435 604
 	ops->tofloat = sol_f_not_impl;
436
-	ops->tostring = sol_f_not_impl;
605
+	ops->tostring = sol_f_default_tostring;
606
+	ops->repr = sol_f_default_repr;
437 607
 	ops->init = sol_f_no_op;
438 608
 	ops->free = sol_f_no_op;
439 609
 }

+ 51
- 0
test.sol View File

@@ -304,8 +304,10 @@ print(e)
304 304
 
305 305
 print('--- Basic buffers')
306 306
 
307
+print('(buffer.fromstring = ', buffer.fromstring, ')')
307 308
 b = buffer.fromstring("Hello, world!")
308 309
 print(b)
310
+print('(b.get = ', b.get, ')')
309 311
 print(b:get(buffer.type.cstr))
310 312
 b:set(buffer.type.char, "Q")
311 313
 b:set(buffer.type.char, "L", 2)
@@ -316,5 +318,54 @@ print(b:get(buffer.type.uint32))
316 318
 b:set(buffer.type.uint32, 1886545252)
317 319
 print(b:get(buffer.type.uint32))
318 320
 print(b:get(buffer.type.cstr))
321
+q = buffer.fromaddress(b:address(), b:size())
322
+print(q:get(buffer.type.cstr))
323
+q:set(buffer.type.cstr, "Goodbye!")
324
+print(q:get(buffer.type.cstr), b:get(buffer.type.cstr))
325
+
326
+s = "A string!"
327
+b = buffer.fromobject(s)
328
+prepr(s)
329
+print('...is a', buffer.objtype[b:get(buffer.type.int, 0)])
330
+print('(buffer.sizeof.ptr = ', buffer.sizeof.ptr, ')')
331
+print('(buffer.sizeof.int = ', buffer.sizeof.int, ')')
332
+print('(buffer.sizeof.int*2 = ', buffer.sizeof.int*2, ')')
333
+print('(buffer.sizeof.int*2 + buffer.sizeof.ptr = ', buffer.sizeof.int*2 + (buffer.sizeof.ptr), ')')
334
+print('...with value:', b:get(buffer.type.ptr, buffer.sizeof.int*2 + (buffer.sizeof.ptr)):get(buffer.type.cstr))
335
+
336
+print('--- IO redirection')
337
+
338
+oldstdout = io.stdout
339
+io.stdout = io.open('stdout', io.MODE_WRITE|io.MODE_TRUNCATE)
340
+
341
+print('A line!')
342
+print('An object:', {a=1, b=2, c="turkey"})
343
+print('Something mysterious :o')
344
+io.stdout:write('Writing directly to a file :D')
345
+io.stdout:flush()
346
+
347
+io.stdout = oldstdout
348
+
349
+print('...restored stdout.')
350
+
351
+f = io.open('stdout', io.MODE_READ)
352
+s = f:read(io.ALL)
353
+print('Buffered output was:')
354
+prepr(s)
355
+f = None
356
+
357
+print('...second time.')
358
+
359
+io.stdout = io.open('stdout', io.MODE_WRITE|io.MODE_TRUNCATE)
360
+
361
+print('Hey there!')
362
+print('l'+'ol'*32)
363
+io.stdout:flush()
364
+
365
+io.stdout = oldstdout
366
+
367
+print('...restored.')
368
+print('Output was:')
369
+prepr(io.open('stdout', io.MODE_READ):read(io.ALL))
319 370
 
320 371
 print('--- All done!')

Loading…
Cancel
Save