example scripts update; new BUILD_MODE=CHECKMEM; patched some memory leaks

This commit is contained in:
cozis
2022-12-09 14:26:31 +01:00
parent 5284251e19
commit 1671d178e4
5 changed files with 94 additions and 97 deletions
+19 -39
View File
@@ -46,8 +46,7 @@ fun parseMethod(scan: Scanner) {
method = ""; method = "";
do { do {
method = cat(method, char); method = cat(method, char);
scan->consume(); char = scan->consume();
char = scan->current();
} while char != none and isUpper(char); } while char != none and isUpper(char);
return method, none; return method, none;
@@ -59,16 +58,13 @@ fun parsePort(scan: Scanner) {
char = scan->current(); char = scan->current();
if char == ":" and isDigit(scan->hint(1)): { if char == ":" and isDigit(scan->hint(1)): {
scan->consume(); # Skip the ":" char = scan->consume(); # Skip the ":"
char = scan->current();
port = 0; port = 0;
do { do {
digit = ord(char) digit = ord(char) - ord("0");
- ord("0");
port = port * 10 + digit; port = port * 10 + digit;
scan->consume(); char = scan->consume();
char = scan->current();
} while char != none and isDigit(char); } while char != none and isDigit(char);
} }
return port; return port;
@@ -90,8 +86,7 @@ fun parseHost(scan: Scanner) {
name = ""; name = "";
do { do {
name = cat(name, char); name = cat(name, char);
scan->consume(); char = scan->consume();
char = scan->current();
} while char != none and isHostname(char); } while char != none and isHostname(char);
port = parsePort(scan); port = parsePort(scan);
@@ -104,8 +99,7 @@ fun parsePath(scan: Scanner) {
char = scan->current(); char = scan->current();
if char != none and char == "/": { if char != none and char == "/": {
path = cat(path, char); path = cat(path, char);
scan->consume(); char = scan->consume();
char = scan->current();
} else { } else {
if char == none or not isPChar(char): if char == none or not isPChar(char):
return none, "Invalid character in place of path"; return none, "Invalid character in place of path";
@@ -114,14 +108,12 @@ fun parsePath(scan: Scanner) {
while char != none and isPChar(char): { while char != none and isPChar(char): {
do { do {
path = cat(path, char); path = cat(path, char);
scan->consume(); char = scan->consume();
char = scan->current();
} while char != none and isPChar(char); } while char != none and isPChar(char);
if char == none or char != "/": if char == none or char != "/":
break; break;
path = cat(path, char); path = cat(path, char);
scan->consume(); char = scan->consume();
char = scan->current();
} }
return path; return path;
@@ -139,12 +131,9 @@ fun parseQuery(scan: Scanner) {
char = scan->current(); char = scan->current();
if char != none and char == "?": { if char != none and char == "?": {
scan->consume(); # Consume the "?"
query = ""; query = "";
while isQuery(char = scan->current()): { while isQuery(char = scan->consume()):
query = cat(query, char); query = cat(query, char);
scan->consume();
}
} else } else
query = none; query = none;
@@ -161,12 +150,9 @@ fun parseFragment(scan: Scanner) {
char = scan->current(); char = scan->current();
if char != none and char == "#": { if char != none and char == "#": {
scan->consume(); # Consume the "#"
fragment = ""; fragment = "";
while isFragment(char = scan->current()): { while isFragment(char = scan->consume()):
fragment = cat(fragment, char); fragment = cat(fragment, char);
scan->consume();
}
} else } else
fragment = none; fragment = none;
@@ -207,8 +193,7 @@ fun parseSchema(scan: Scanner) {
schema = ""; schema = "";
do { do {
schema = cat(schema, char); schema = cat(schema, char);
scan->consume(); char = scan->consume();
char = scan->current();
} while isSchema(char); } while isSchema(char);
if char == ":": if char == ":":
@@ -230,7 +215,7 @@ fun parseURL(scan: Scanner) {
schema = parseSchema(scan); schema = parseSchema(scan);
if followsAuthority(scan): { if followsAuthority(scan): {
consume(scan, 2); scan->consume(2);
host, error = parseHost(scan); host, error = parseHost(scan);
if error != none: if error != none:
@@ -272,14 +257,12 @@ fun parseVersion(scan: Scanner) {
or scan->hint(4) != "/" or not isDigit(scan->hint(5)): or scan->hint(4) != "/" or not isDigit(scan->hint(5)):
return none, "Invalid version token"; return none, "Invalid version token";
scan->consume(5); char = scan->consume(5);
major = ord(scan->current()) major = ord(char) - ord("0");
- ord("0");
if scan->hint(1) != "." and isDigit(scan->hint(2)): { if scan->hint(1) != "." and isDigit(scan->hint(2)): {
scan->consume(2); char = scan->consume(2);
minor = ord(scan->current()) minor = ord(char) - ord("0");
- ord("0");
} else } else
minor = 0; minor = 0;
scan->consume(); scan->consume();
@@ -345,22 +328,19 @@ fun parse(src: String) {
name = ""; name = "";
do { do {
name = cat(name, char); name = cat(name, char);
scan->consume(); char = scan->consume();
char = scan->current();
} while char != ":" and char != none; } while char != ":" and char != none;
if char == none: if char == none:
return none, "Invalid header (missing \":\" after name)"; return none, "Invalid header (missing \":\" after name)";
scan->consume(); scan->consume();
scan->consumeSpaces(); char = scan->consumeSpaces();
char = scan->current();
# Header body until \r # Header body until \r
body = ""; body = "";
do { do {
body = cat(body, char); body = cat(body, char);
scan->consume(); char = scan->consume();
char = scan->current();
} while char != "\r" and char != none; } while char != "\r" and char != none;
headers[name] = body; headers[name] = body;
+42 -48
View File
@@ -3,18 +3,17 @@ scan = import("scan.noja");
newScanner = scan.newScanner; newScanner = scan.newScanner;
Scanner = scan.Scanner; Scanner = scan.Scanner;
isDigit = scan.isDigit; isDigit = scan.isDigit;
ord = string.ord;
fun parseString(scan: Scanner) { fun parseString(scan: Scanner) {
assert(scan->current() == '"'); assert(scan->current() == '"');
scan->consume(); # Consume the opening " char = scan->consume(); # Consume the opening "
temp = ""; temp = "";
char = scan->current();
while char != '"' and char != none: { while char != '"' and char != none: {
temp = string.cat(temp, char); temp = string.cat(temp, char);
scan->consume(); char = scan->consume();
char = scan->current();
} }
if char == none: { if char == none: {
@@ -36,16 +35,17 @@ fun parseObject(scan: Scanner) {
scan->consume(); scan->consume();
obj = {}; obj = {};
scan->consumeSpaces(); char = scan->consumeSpaces();
if scan->current() != '}': do { if char != '}': do {
key, err = parseValue(scan); key, err = parseValue(scan);
if err != none: if err != none:
return none, err; return none, err;
if type(key) != String: if type(key) != String:
return none, "Object key isn't a string"; return none, "Object key isn't a string";
scan->consumeSpaces(); char = scan->consumeSpaces();
if scan->current() != ':': if char != ':':
return none, "Missing ':' separator after key"; return none, "Missing ':' separator after key";
scan->consume(); scan->consume();
@@ -57,11 +57,11 @@ fun parseObject(scan: Scanner) {
return none, "Duplicate key in object"; return none, "Duplicate key in object";
obj[key] = val; obj[key] = val;
scan->consumeSpaces(); char = scan->consumeSpaces();
if scan->current() == '}': if char == '}':
done = true; done = true;
else { else {
if scan->current() != ',': if char != ',':
return none, "Invalid character where either ',' or '}' were expected"; return none, "Invalid character where either ',' or '}' were expected";
scan->consume(); # Consume the "," scan->consume(); # Consume the ","
done = false; done = false;
@@ -79,16 +79,16 @@ fun parseArray(scan: Scanner) {
array = []; array = [];
scan->consumeSpaces(); char = scan->consumeSpaces();
if scan->current() != ']': do { if char != ']': do {
val, err = parseValue(scan); val, err = parseValue(scan);
if err != none: if err != none:
return none, err; return none, err;
array[count(array)] = val; array[count(array)] = val;
scan->consumeSpaces(); char = scan->consumeSpaces();
if scan->current() == ']': if char == ']':
done = true; done = true;
else { else {
if scan->current() != ',': if scan->current() != ',':
@@ -105,21 +105,21 @@ fun parseArray(scan: Scanner) {
fun parseFalse(scan: Scanner) { fun parseFalse(scan: Scanner) {
assert(scan->current() == 'f'); assert(scan->current() == 'f');
scan->consume(); char = scan->consume();
if scan->current() != 'a': if char != 'a':
return none, "Invalid character after 'f'"; return none, "Invalid character after 'f'";
scan->consume(); char = scan->consume();
if scan->current() != 'l': if char != 'l':
return none, "Invalid character after 'fa'"; return none, "Invalid character after 'fa'";
scan->consume(); char = scan->consume();
if scan->current() != 's': if char != 's':
return none, "Invalid character after 'fal'"; return none, "Invalid character after 'fal'";
scan->consume(); char = scan->consume();
if scan->current() != 'e': if char != 'e':
return none, "Invalid character after 'fals'"; return none, "Invalid character after 'fals'";
scan->consume(); scan->consume();
@@ -129,17 +129,17 @@ fun parseFalse(scan: Scanner) {
fun parseTrue(scan: Scanner) { fun parseTrue(scan: Scanner) {
assert(scan->current() == 't'); assert(scan->current() == 't');
scan->consume(); char = scan->consume();
if scan->current() != 'r': if char != 'r':
return none, "Invalid character after 't'"; return none, "Invalid character after 't'";
scan->consume(); char = scan->consume();
if scan->current() != 'u': if char != 'u':
return none, "Invalid character after 'tr'"; return none, "Invalid character after 'tr'";
scan->consume(); char = scan->consume();
if scan->current() != 'e': if char != 'e':
return none, "Invalid character after 'tru'"; return none, "Invalid character after 'tru'";
scan->consume(); scan->consume();
@@ -149,17 +149,17 @@ fun parseTrue(scan: Scanner) {
fun parseNull(scan: Scanner) { fun parseNull(scan: Scanner) {
assert(scan->current() == 'n'); assert(scan->current() == 'n');
scan->consume(); char = scan->consume();
if scan->current() != 'u': if char != 'u':
return none, "Invalid character after 'n'"; return none, "Invalid character after 'n'";
scan->consume(); char = scan->consume();
if scan->current() != 'l': if char != 'l':
return none, "Invalid character after 'nu'"; return none, "Invalid character after 'nu'";
scan->consume(); char = scan->consume();
if scan->current() != 'l': if char != 'l':
return none, "Invalid character after 'nul'"; return none, "Invalid character after 'nul'";
scan->consume(); scan->consume();
@@ -167,9 +167,8 @@ fun parseNull(scan: Scanner) {
} }
fun integerFromDigit(char: String) { fun integerFromDigit(char: String) {
assert(count(char) == 1); assert(isDigit(char));
return string.ord(char) return ord(char) - ord('0');
- string.ord('0');
} }
fun parseNumber(scan: Scanner) { fun parseNumber(scan: Scanner) {
@@ -180,9 +179,8 @@ fun parseNumber(scan: Scanner) {
if char == '+' or char == '-': { if char == '+' or char == '-': {
sign = {'+': 1, '-': -1}[char]; sign = {'+': 1, '-': -1}[char];
scan->consume();
char = scan->current(); char = scan->consume();
if not isDigit(char): if not isDigit(char):
return none, "Invalid character after +/-"; return none, "Invalid character after +/-";
} }
@@ -194,23 +192,20 @@ fun parseNumber(scan: Scanner) {
n = integerFromDigit(char); n = integerFromDigit(char);
temp = temp * 10 + n; temp = temp * 10 + n;
scan->consume(); char = scan->consume();
char = scan->current();
} while isDigit(char); } while isDigit(char);
if char == '.' and isDigit(scan->hint(1)): { if char == '.' and isDigit(scan->hint(1)): {
scan->consume(); # Consume the dot char = scan->consume(); # Consume the dot
char = scan->current();
q = 1.0; q = 1.0;
do { do {
q = q / 10; q = q / 10;
n = integerFromDigit(char); n = integerFromDigit(char);
temp = temp + q * n; temp = temp + q * n;
scan->consume(); char = scan->consume();
char = scan->current();
} while isDigit(char); } while isDigit(char);
} }
@@ -240,8 +235,7 @@ fun parseValue(scan: Scanner) {
'9': parseNumber '9': parseNumber
}; };
scan->consumeSpaces(); char = scan->consumeSpaces();
char = scan->current();
if char == none: { if char == none: {
val = none; val = none;
err = "Source ended where a value was expected"; err = "Source ended where a value was expected";
+7 -3
View File
@@ -26,11 +26,15 @@ fun consume(scan: Scanner, n: int = 1) {
assert(n > 0); assert(n > 0);
limit = count(scan.src); limit = count(scan.src);
scan.i = min(scan.i + n, limit); scan.i = min(scan.i + n, limit);
return current(scan);
} }
fun consumeSpaces(scan: Scanner) fun consumeSpaces(scan: Scanner) {
while isSpace(current(scan)): char = current(scan);
consume(scan); while isSpace(char):
char = consume(scan);
return char;
}
fun newScanner(src: String) { fun newScanner(src: String) {
scan = { scan = {
+4 -1
View File
@@ -52,7 +52,7 @@ LFLAGS = -lm
# Can be one of: YES, NO # Can be one of: YES, NO
USING_VALGRIND = NO USING_VALGRIND = NO
# May be one of: COVERAGE, RELEASE, DEBUG # May be one of: COVERAGE, RELEASE, DEBUG, CHECKMEM
BUILD_MODE = RELEASE BUILD_MODE = RELEASE
# Changing the BUILD_MODE will add one of the # Changing the BUILD_MODE will add one of the
@@ -62,6 +62,9 @@ BUILD_MODE = RELEASE
CFLAGS_DEBUG = -DDEBUG -g CFLAGS_DEBUG = -DDEBUG -g
LFLAGS_DEBUG = LFLAGS_DEBUG =
CFLAGS_CHECKMEM = -fsanitize=address -g
LFLAGS_CHECKMEM = -fsanitize=address
CFLAGS_RELEASE = -DNDEBUG -O3 CFLAGS_RELEASE = -DNDEBUG -O3
LFLAGS_RELEASE = LFLAGS_RELEASE =
+21 -5
View File
@@ -134,13 +134,18 @@ static int bin_import(Runtime *runtime, Object **argv, unsigned int argc, Object
UNUSED(errname); UNUSED(errname);
Object *o_none = Object_NewNone(heap, error); Object *o_none = Object_NewNone(heap, error);
if(o_none == NULL) if(o_none == NULL) {
Source_Free(src);
return -1; return -1;
}
Object *o_err = Object_FromString(sub_error.message, -1, heap, error); Object *o_err = Object_FromString(sub_error.message, -1, heap, error);
if(o_err == NULL) if(o_err == NULL) {
Source_Free(src);
return -1; return -1;
}
Source_Free(src);
Error_Free(&sub_error); Error_Free(&sub_error);
rets[0] = o_none; rets[0] = o_none;
rets[1] = o_err; rets[1] = o_err;
@@ -156,19 +161,30 @@ static int bin_import(Runtime *runtime, Object **argv, unsigned int argc, Object
UNUSED(errname); UNUSED(errname);
Object *o_none = Object_NewNone(heap, error); Object *o_none = Object_NewNone(heap, error);
if(o_none == NULL) return -1; if(o_none == NULL) {
Source_Free(src);
Executable_Free(exe);
return -1;
}
Object *o_err = Object_FromString(sub_error.message, -1, heap, error); Object *o_err = Object_FromString(sub_error.message, -1, heap, error);
if(o_err == NULL) return -1; if(o_err == NULL) {
Source_Free(src);
Executable_Free(exe);
return -1;
}
Error_Free(&sub_error); Error_Free(&sub_error);
rets[0] = o_none; rets[0] = o_none;
rets[1] = o_err; rets[1] = o_err;
Source_Free(src);
Executable_Free(exe);
return 2; return 2;
} }
ASSERT(retc == 1); ASSERT(retc == 1);
Error_Free(&sub_error); Error_Free(&sub_error);
Source_Free(src);
Executable_Free(exe);
rets[0] = sub_rets[0]; rets[0] = sub_rets[0];
return 1; return 1;
} }