From 26fa0559b0689a4647c38a2275c5880148248718 Mon Sep 17 00:00:00 2001 From: Syndamia Date: Sat, 1 Nov 2025 18:13:33 +0200 Subject: feat(src/StringConsumer): Add higher order consumers, integer, binary operation and if keywords consumers Higher order consumers are called that way because they use other (base) consumers in their logic. In a sense, the other consumers are parameters to the higher order consumers. --- .../BaseConsumers/BinaryOperatorConsumer.cl | 18 +++++++++++++ .../BaseConsumers/IntegerConsumer.cl | 21 +++++++++++++++ .../BaseConsumers/KeywordsIfConsumer.cl | 15 +++++++++++ .../BaseConsumers/WhitespaceConsumer.cl | 13 +++++++++ .../HigherOrderConsumers/ExpressionConsumer.cl | 19 +++++++++++++ .../HigherOrderConsumers/IfConsumer.cl | 14 ++++++++++ src/StringConsumer/IHigherOrderConsumer.cl | 11 ++++++++ src/StringConsumer/IWordConsumer.cl | 13 +++++++++ src/StringConsumer/IWordsConsumer.cl | 31 +++++++++++++++++++--- src/StringConsumer/StringConsumerEngine.cl | 2 ++ src/StringConsumer/WhitespaceConsumer.cl | 13 --------- 11 files changed, 153 insertions(+), 17 deletions(-) create mode 100644 src/StringConsumer/BaseConsumers/BinaryOperatorConsumer.cl create mode 100644 src/StringConsumer/BaseConsumers/IntegerConsumer.cl create mode 100644 src/StringConsumer/BaseConsumers/KeywordsIfConsumer.cl create mode 100644 src/StringConsumer/BaseConsumers/WhitespaceConsumer.cl create mode 100644 src/StringConsumer/HigherOrderConsumers/ExpressionConsumer.cl create mode 100644 src/StringConsumer/HigherOrderConsumers/IfConsumer.cl create mode 100644 src/StringConsumer/IHigherOrderConsumer.cl create mode 100644 src/StringConsumer/IWordConsumer.cl delete mode 100644 src/StringConsumer/WhitespaceConsumer.cl (limited to 'src/StringConsumer') diff --git a/src/StringConsumer/BaseConsumers/BinaryOperatorConsumer.cl b/src/StringConsumer/BaseConsumers/BinaryOperatorConsumer.cl new file mode 100644 index 0000000..8e7288c --- /dev/null +++ b/src/StringConsumer/BaseConsumers/BinaryOperatorConsumer.cl @@ -0,0 +1,18 @@ +class BinaryOperatorConsumer inherits IWordsConsumer { + init() : IStringConsumer {{ + matched_words <- matched_words + .push("+") + .push("-") + .push("*") + .push("/") + .push("<") + .push("<=") + .push("=") + ; + self; + }}; + + token() : IToken { + new BinaryOperatorToken + }; +}; diff --git a/src/StringConsumer/BaseConsumers/IntegerConsumer.cl b/src/StringConsumer/BaseConsumers/IntegerConsumer.cl new file mode 100644 index 0000000..5b4cd82 --- /dev/null +++ b/src/StringConsumer/BaseConsumers/IntegerConsumer.cl @@ -0,0 +1,21 @@ +class IntegerConsumer inherits IWordsConsumer { + init() : IStringConsumer {{ + matched_words <- matched_words + .push("0") + .push("1") + .push("2") + .push("3") + .push("4") + .push("5") + .push("6") + .push("7") + .push("8") + .push("9") + ; + self; + }}; + + token() : IToken { + new IntegerToken + }; +}; diff --git a/src/StringConsumer/BaseConsumers/KeywordsIfConsumer.cl b/src/StringConsumer/BaseConsumers/KeywordsIfConsumer.cl new file mode 100644 index 0000000..9bd76e9 --- /dev/null +++ b/src/StringConsumer/BaseConsumers/KeywordsIfConsumer.cl @@ -0,0 +1,15 @@ +class KeywordsIfConsumer inherits IWordsConsumer { + init() : IStringConsumer {{ + matched_words <- matched_words + .push("if") + .push("then") + .push("else") + .push("fi") + ; + self; + }}; + + token() : IToken { + new KeywordToken + }; +}; diff --git a/src/StringConsumer/BaseConsumers/WhitespaceConsumer.cl b/src/StringConsumer/BaseConsumers/WhitespaceConsumer.cl new file mode 100644 index 0000000..3a8c4dc --- /dev/null +++ b/src/StringConsumer/BaseConsumers/WhitespaceConsumer.cl @@ -0,0 +1,13 @@ +class WhitespaceConsumer inherits IWordsConsumer { + init() : IStringConsumer {{ + matched_words <- matched_words + .push(" ") + .push("\t") + ; + self; + }}; + + token() : IToken { + new WhitespaceToken + }; +}; diff --git a/src/StringConsumer/HigherOrderConsumers/ExpressionConsumer.cl b/src/StringConsumer/HigherOrderConsumers/ExpressionConsumer.cl new file mode 100644 index 0000000..592611e --- /dev/null +++ b/src/StringConsumer/HigherOrderConsumers/ExpressionConsumer.cl @@ -0,0 +1,19 @@ +class ExpressionConsumer inherits IHigherOrderConsumer { + integerc: IStringConsumer <- (new IntegerConsumer).init(); + binaryopc: IStringConsumer <- (new BinaryOperatorConsumer).init(); + + consume(s: String) : Int {{ + consumed_length <- 0; + if did(integerc.consume(s)) + then + token <- integerc.token() + else if did(binaryopc.consume(s)) + then + token <- binaryopc.token() + else + void + fi + fi; + consumed_length; + }}; +}; diff --git a/src/StringConsumer/HigherOrderConsumers/IfConsumer.cl b/src/StringConsumer/HigherOrderConsumers/IfConsumer.cl new file mode 100644 index 0000000..431f79b --- /dev/null +++ b/src/StringConsumer/HigherOrderConsumers/IfConsumer.cl @@ -0,0 +1,14 @@ +class IfConsumer inherits IHigherOrderConsumer { + ifc: IStringConsumer <- (new KeywordsIfConsumer).init(); + + consume(s: String) : Int {{ + consumed_length <- 0; + if did(ifc.consume(s)) + then + token <- ifc.token() + else + void + fi; + consumed_length; + }}; +}; diff --git a/src/StringConsumer/IHigherOrderConsumer.cl b/src/StringConsumer/IHigherOrderConsumer.cl new file mode 100644 index 0000000..e7325d2 --- /dev/null +++ b/src/StringConsumer/IHigherOrderConsumer.cl @@ -0,0 +1,11 @@ +class IHigherOrderConsumer inherits IStringConsumer { + token: IToken; + + token() : IToken { + token + }; + + did(length: Int) : Bool { + 0 < (consumed_length <- consumed_length + length) + }; +}; diff --git a/src/StringConsumer/IWordConsumer.cl b/src/StringConsumer/IWordConsumer.cl new file mode 100644 index 0000000..a809cd2 --- /dev/null +++ b/src/StringConsumer/IWordConsumer.cl @@ -0,0 +1,13 @@ +class IWordConsumer inherits IStringConsumer { + word: String; + + consume(s: String) : Int {{ + consumed_length <- 0; + if s.substr(0, word.length()) = word + then + consumed_length <- word.length() + else + consumed_length + fi; + }}; +}; diff --git a/src/StringConsumer/IWordsConsumer.cl b/src/StringConsumer/IWordsConsumer.cl index 4c184bf..a1c22ba 100644 --- a/src/StringConsumer/IWordsConsumer.cl +++ b/src/StringConsumer/IWordsConsumer.cl @@ -37,16 +37,37 @@ class WordList inherits System { any_starts(s: String, start: Int) : Int { if or(word = "", s.length() <= start) - then 0 + then + 0 + else if and(s.length() < start + word.length(), not isvoid next) + then + next.any_starts(s, start) else if s.substr(start, word.length()) = word - then word.length() + then + word.length() else if isvoid next - then 0 - else next.any_starts(s, start) + then + 0 + else + next.any_starts(s, start) + fi fi fi fi }; + + empty() : Bool { + if not (word = "") + then + false + else if isvoid next + then + true + else + next.empty() + fi + fi + }; }; class IWordsConsumer inherits IStringConsumer { @@ -56,6 +77,8 @@ class IWordsConsumer inherits IStringConsumer { let word_length: Int <- 0 in { + assert(not matched_words.empty(), "consume", "object of class hasn't been initialised!"); + consumed_length <- 0; while 0 < (word_length <- matched_words.any_starts(s, consumed_length)) loop diff --git a/src/StringConsumer/StringConsumerEngine.cl b/src/StringConsumer/StringConsumerEngine.cl index 6f07d2e..4f4f65f 100644 --- a/src/StringConsumer/StringConsumerEngine.cl +++ b/src/StringConsumer/StringConsumerEngine.cl @@ -1,6 +1,8 @@ class StringConsumerEngine inherits System { consumers: ConsumerList <- (new ConsumerList) .push((new WhitespaceConsumer).init()) + .push((new ExpressionConsumer).init()) + .push((new IfConsumer).init()) ; str: String; diff --git a/src/StringConsumer/WhitespaceConsumer.cl b/src/StringConsumer/WhitespaceConsumer.cl deleted file mode 100644 index 3a8c4dc..0000000 --- a/src/StringConsumer/WhitespaceConsumer.cl +++ /dev/null @@ -1,13 +0,0 @@ -class WhitespaceConsumer inherits IWordsConsumer { - init() : IStringConsumer {{ - matched_words <- matched_words - .push(" ") - .push("\t") - ; - self; - }}; - - token() : IToken { - new WhitespaceToken - }; -}; -- cgit v1.3.1-26-gb76a