diff options
| Commit | b43c94ca62a747f2f9fb222cdf887c041dd544bb (patch) | |
|---|---|---|
| Author | 2025-11-01 16:28:08 +0200 | |
| Committer | 2025-11-01 16:28:08 +0200 | |
| Files | 43e0ea846844257cf46055e68cc2661056b05965 /src | |
| cool-self-hosted-b43c94ca62a747f2f9fb222cdf887c041dd544bb.tar cool-self-hosted-b43c94ca62a747f2f9fb222cdf887c041dd544bb.tar.gz cool-self-hosted-b43c94ca62a747f2f9fb222cdf887c041dd544bb.zip | ||
| Parent | 0830615386f036acc55a72b2548efb65526c761f (diff) | |
feat!: Add basic lexer components
8 files changed, 227 insertions, 0 deletions
| -rw-r--r-- | src/StringConsumer/ConsumerList.cl | 52 | ||||
| -rw-r--r-- | src/StringConsumer/IStringConsumer.cl | 20 | ||||
| -rw-r--r-- | src/StringConsumer/StringConsumerEngine.cl | 36 | ||||
| -rw-r--r-- | src/StringConsumer/WhitespaceConsumer.cl | 15 | ||||
| -rw-r--r-- | src/System.cl | 60 | ||||
| -rw-r--r-- | src/Token/IToken.cl | 24 | ||||
| -rw-r--r-- | src/Token/WhitespaceToken.cl | 10 | ||||
| -rw-r--r-- | src/main.cl | 10 |
diff --git a/src/StringConsumer/ConsumerList.cl b/src/StringConsumer/ConsumerList.cl new file mode 100644 index 0000000..526996c --- /dev/null +++ b/src/StringConsumer/ConsumerList.cl @@ -0,0 +1,52 @@ +class ConsumerList inherits System { + item: IStringConsumer; + next: ConsumerList; + + init(value: IStringConsumer, tail: Object) : ConsumerList {{ + assert(not (isvoid value), "init", "value argument cannot be void!"); + assert(isvoid item, "init", "List has already been initialised!"); + + item <- value; + if isvoid tail then + void + else + case tail of + cl: ConsumerList => next <- cl; + o: Object => assert(false, "init", "tail argument can be either a ConsumerList or void!"); + esac + fi; + + self; + }}; + + push(value: IStringConsumer) : ConsumerList {{ + assert(not (isvoid value), "push", "value argument cannot be void!"); + + if isvoid item + then + item <- value + else if isvoid next + then + next <- (new ConsumerList).init(value, void) + else + next.push(value) + fi + fi; + self; + }}; + + find(s: String) : Object {{ + assert(not (isvoid item), "find", "list isn't initialised!"); + + if 0 < item.consume(s) + then + item + else if isvoid next + then + void + else + next.find(s) + fi + fi; + }}; +}; diff --git a/src/StringConsumer/IStringConsumer.cl b/src/StringConsumer/IStringConsumer.cl new file mode 100644 index 0000000..20a4f3a --- /dev/null +++ b/src/StringConsumer/IStringConsumer.cl @@ -0,0 +1,20 @@ +class IStringConsumer inherits System { + consume(s: String) : Int { + not_implemented_retint("consume") + }; + + token() : IToken {{ + not_implemented("token"); + new IToken; + }}; + + out() : Object { + not_implemented("out") + }; + +--- + consumed_length: Int; + consumed_length() : Int { + consumed_length + }; +}; diff --git a/src/StringConsumer/StringConsumerEngine.cl b/src/StringConsumer/StringConsumerEngine.cl new file mode 100644 index 0000000..dc7e202 --- /dev/null +++ b/src/StringConsumer/StringConsumerEngine.cl @@ -0,0 +1,36 @@ +class StringConsumerEngine inherits System { + consumers: ConsumerList <- (new ConsumerList) + .push(new WhitespaceConsumer) + ; + + str: String; + + init(code: String) : Object {{ + assert(not (code = ""), "init", "input code cannot be empty!"); + assert(str = "", "init", "already initialised!"); + + str <- code; + }}; + + try_consume() : Bool { + let + consumer: Object <- consumers.find(str) + in + if isvoid consumer + then + false + else + case consumers.find(str) of + c: IStringConsumer => { + str <- str.substr(c.consumed_length(), str.length() - c.consumed_length()); + true; + }; + o: Object => false; + esac + fi + }; + + out() : Object { + out_string(str) + }; +}; diff --git a/src/StringConsumer/WhitespaceConsumer.cl b/src/StringConsumer/WhitespaceConsumer.cl new file mode 100644 index 0000000..4c0b8b5 --- /dev/null +++ b/src/StringConsumer/WhitespaceConsumer.cl @@ -0,0 +1,15 @@ +class WhitespaceConsumer inherits IStringConsumer { + consume(s: String) : Int {{ + consumed_length <- 0; + while or(s.substr(consumed_length, 1) = " ", + s.substr(consumed_length, 1) = "\t") + loop + consumed_length <- consumed_length + 1 + pool; + consumed_length; + }}; + + token() : IToken { + new WhitespaceToken + }; +}; diff --git a/src/System.cl b/src/System.cl new file mode 100644 index 0000000..12f2210 --- /dev/null +++ b/src/System.cl @@ -0,0 +1,60 @@ +-- "Global" constructs + +class System inherits IO { + void: Object <- while false loop 0 pool; + + or(p: Bool, q: Bool) : Bool { + if p then true + else + if q then true + else false + fi + fi + }; + + and(p: Bool, q: Bool) : Bool { + if p then + if q then true + else false + fi + else false + fi + }; + + assert(condition: Bool, method_name: String, error_msg: String) : Object { + if not condition then + { + out_string("\n") + .out_string("Assertion failed at ") + .out_string(type_name()) + .out_string(".") + .out_string(method_name) + .out_string("(): ") + .out_string(error_msg) + .out_string("\n"); + abort(); + } + else + void + fi + }; + + not_implemented(method_name: String) : Object {{ + out_string("\n") + .out_string("Method ") + .out_string(type_name()) + .out_string(".") + .out_string(method_name) + .out_string("() isn't implemented!") + .out_string("\n"); + abort(); + }}; + not_implemented_retint(method_name: String) : Int {{ + not_implemented(method_name); + 0; + }}; + not_implemented_retstr(method_name: String) : String {{ + not_implemented(method_name); + ""; + }}; +}; diff --git a/src/Token/IToken.cl b/src/Token/IToken.cl new file mode 100644 index 0000000..05282ab --- /dev/null +++ b/src/Token/IToken.cl @@ -0,0 +1,24 @@ +class IToken inherits System { +--- + name() : String { + not_implemented_retstr("name") + }; + + value() : String { + not_implemented_retstr("value") + }; + +--- + id: Int; + + id() : Int { + id + }; + + init(iid: Int) : Object {{ + assert(iid = 0, "init", "ID 0 is not allowed for a token!"); + assert(not (id = 0), "init", "token object '".concat(name()).concat("' is already initialized!")); + id <- iid; + void; + }}; +}; diff --git a/src/Token/WhitespaceToken.cl b/src/Token/WhitespaceToken.cl new file mode 100644 index 0000000..e0d70c0 --- /dev/null +++ b/src/Token/WhitespaceToken.cl @@ -0,0 +1,10 @@ +class WhitespaceToken inherits IToken { + name() : String { + "WHITESPACE" + }; + + -- We'll never use the whitespace value + value() : String { + "" + }; +}; diff --git a/src/main.cl b/src/main.cl new file mode 100644 index 0000000..9ebb87b --- /dev/null +++ b/src/main.cl @@ -0,0 +1,10 @@ +class Main inherits System { + sce: StringConsumerEngine <- new StringConsumerEngine; + + main() : Object {{ + sce.init(" abc"); + sce.try_consume(); + sce.try_consume(); + sce.out(); + }}; +}; |
