From 8cac46440bbacd7a1747aecd47953d3d5a8e534c Mon Sep 17 00:00:00 2001 From: cozis Date: Mon, 15 Aug 2022 04:16:30 +0200 Subject: [PATCH] updated code sample in the readme --- README.md | 34 +++++++++++++++++++--------------- examples/json/json.noja | 27 +++++++++++++++------------ src/lib/compiler/codegen.c | 14 +++++++++++++- 3 files changed, 47 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index b20b398..bf8a103 100644 --- a/README.md +++ b/README.md @@ -21,25 +21,29 @@ Here's an example of a noja program that orders the items in list using a bubble ``` L = [3, 2, 1]; -do { - swapped = false; +fun swap(a: int, b: int) + return b, a; - i = 0; - while i < count(L)-1 and not swapped: { +fun order(L: List) { - if L[i+1] < L[i]: { - - swapped = true; - tmp = L[i+1]; - L[i+1] = L[i]; - L[i] = tmp; + do { + swapped = false; + + i = 0; + while i < count(L)-1 and not swapped: { + + swapped = L[i+1] < L[i]; + if swapped: + L[i], L[i+1] = swap(L[i], L[i+1]); + + i = i+1; } - - i = i + 1; - } -} while swapped; + } while swapped; +} -print(L, '\n'); # Outputs [1, 2, 3] +print(L, '\n'); # [3, 2, 1] +order(L); +print(L, '\n'); # [1, 2, 3] ``` ## Implementation Overview diff --git a/examples/json/json.noja b/examples/json/json.noja index 8f37a10..4655a3e 100644 --- a/examples/json/json.noja +++ b/examples/json/json.noja @@ -1,21 +1,21 @@ -fun isSpace(c) +fun isSpace(c: String) return c == " " or c == "\t" or c == "\n"; -fun isDigit(c) { +fun isDigit(c: String) { u = unicode(c); d = u - unicode("0"); return d >= 0 and d <= 9; } -fun skipSpaces(context) { +fun skipSpaces(context: Map) { # Skip zero or more whitespace characters. while context.cur < count(context.str) and isSpace(context.str[context.cur]): context.cur = context.cur + 1; } -fun parseNull(context) { +fun parseNull(context: Map) { assert(context.cur < count(context) and context.str[context.cur] == 'n'); @@ -30,7 +30,7 @@ fun parseNull(context) { return none; } -fun parseTrue(context) { +fun parseTrue(context: Map) { assert(context.cur < count(context) and context.str[context.cur] == 't'); @@ -45,7 +45,7 @@ fun parseTrue(context) { return true; } -fun parseFalse(context) { +fun parseFalse(context: Map) { assert(context.cur < count(context) and context.str[context.cur] == 'f'); @@ -61,14 +61,17 @@ fun parseFalse(context) { return false; } -fun skip(context, test_callback) { +fun dummy() {} +Func = type(dummy); + +fun skip(context: Map, test_callback: Func) { k = context.cur; while k < count(context) and test_callback(context.str[k]): k = k + 1; return k; } -fun parseInteger(context) { +fun parseInteger(context: Map) { assert(context.cur < count(context) and isDigit(context.str[context.cur])); buffer = 0; @@ -84,7 +87,7 @@ fun parseInteger(context) { return buffer; } -fun parseFloating(context) { +fun parseFloating(context: Map) { assert(context.cur < count(context) and isDigit(context.str[context.cur])); # It's ensured by the caller (parseIntegerOrFloating) @@ -117,7 +120,7 @@ fun parseFloating(context) { return buffer; } -fun parseIntegerOrFloating(context) { +fun parseIntegerOrFloating(context: Map) { assert(context.cur < count(context) and isDigit(context.str[context.cur])); # Is the first digit sequence followed by a dot @@ -132,7 +135,7 @@ fun parseIntegerOrFloating(context) { return parseInteger(context); } -fun parseValue(context) { +fun parseValue(context: Map) { if context.cur == count(context): return none, "Source ended where a value was expected"; @@ -159,7 +162,7 @@ fun parseValue(context) { return val, err; } -fun parse(str) { +fun parse(str: String) { context = {str: str, cur: 0}; skipSpaces(context); val, err = parseValue(context); diff --git a/src/lib/compiler/codegen.c b/src/lib/compiler/codegen.c index af5a24d..394e82f 100644 --- a/src/lib/compiler/codegen.c +++ b/src/lib/compiler/codegen.c @@ -208,15 +208,24 @@ static void emitInstrForFuncCallNode(CodegenContext *ctx, CallExprNode *expr, static void emitInstrForArgumentNode(CodegenContext *ctx, ArgumentNode *arg, int argidx) { /* + * // Push the type of the argument * PUSHTYP; - * // What if this isn't a type? + * + * // Evaluate the type annotation and make + * // sure that it evaluated to a type. + * * PUSHTYP; * PUSHTYPTYP; * EQL; * JUMPIFANDPOP argument_annotation_0_not_type; + * + * // If the annotated type and the argument's + * // type match, jump to the argument assignment. * EQL; * JUMPIFANDPOP argument_type_ok; * + * // To the same for the next annotation. + * * PUSHTYP; * * PUSHTYP; @@ -239,6 +248,9 @@ static void emitInstrForArgumentNode(CodegenContext *ctx, ArgumentNode *arg, int * argument_annotation_0_not_a_type: * ERROR "Argument N annotation M isn't a type"; * argument_type_ok: + * + * // At this point we know that the argument has + * // a valid type. * ASS ; * POP 1; */