From b142d94b11b88cce5d2452d7d2a980b8352e8368 Mon Sep 17 00:00:00 2001 From: MaximeBarniaudy Date: Tue, 28 May 2024 14:34:34 +0900 Subject: [PATCH] Delare Stream object in C code and add primitive for stream string matching. Also refactor the rollback mechanism in the grammar parser to give responsibility to the right object. --- grammar_parser.meta | 187 ++++++++++++++++++++++---------------------- minproto.leg | 72 ++++++++++++++++- 2 files changed, 161 insertions(+), 98 deletions(-) diff --git a/grammar_parser.meta b/grammar_parser.meta index 36d3213..d662381 100644 --- a/grammar_parser.meta +++ b/grammar_parser.meta @@ -1,5 +1,8 @@ // ----- Utils ----- +true = (1 == 1); +false = (1 == 0); + Object.contains(item) { for (i in self.length()) { if (self[i] == item) { @@ -109,30 +112,22 @@ Object.subtype(name) { self.new(__name__: name) } // Input stream -Stream = Object.subtype(#Stream); +//Stream = Object.subtype(#Stream); -newStream(string) { - let self = Stream.new( - content: string, - position: 0, - limit: len(string) - ); - self; -} +//newStream(string) { +// let self = Stream.new( +// content: string, +// position: 0, +// limit: len(string) +// ); +// self; +//} -Stream.atEnd() { self.position >= self.limit } +//Stream.atEnd() { self.position >= self.limit } Stream.peek() { !self.atEnd() && self.content[self.position] } -Stream.inc() { !self.atEnd() && { self.position = self.position + 1; } } - -Stream.next() { - !self.atEnd() && { - let c = self.content[self.position]; - self.position = self.position + 1; - c; - } -} +//Stream.inc() { !self.atEnd() && { self.position = self.position + 1; } } -Stream.setLastBegin = () { self.lastBegin = self.position; }; +//Stream.setLastBegin = () { self.lastBegin = self.position; }; // Context @@ -156,27 +151,36 @@ Context.declareVariable(var) { StringLiteral = Object.subtype(#StringLiteral); -StringLiteral.match(stream, context, actions) { - - let n = len(self.string); - let i = 0; - let success = 1; - if (stream.atEnd()) { success = 0; } - let startPosition = stream.position; - - while(i < n && success == 1) { - if (self.string[i] != stream.peek()) { - success = 0; - stream.position = startPosition; - - } else { - i = i + 1; - stream.inc(); - } +StringLiteral.match(stream, context, actions) { + if (stream.match(self.string)) { + stream.position += len(self.string); + true; + } else { + false; } - success; } +//StringLiteral.match(stream, context, actions) { +// +// let n = len(self.string); +// let i = 0; +// let success = 1; +// if (stream.atEnd()) { success = 0; } +// let startPosition = stream.position; +// +// while(i < n && success == 1) { +// if (self.string[i] != stream.peek()) { +// success = 0; +// stream.position = startPosition; +// +// } else { +// i = i + 1; +// stream.inc(); +// } +// } +// success; +//} + // Character Class CharacterClass = Object.subtype(#CharacterClass); @@ -240,7 +244,7 @@ CharacterClass.match(stream, context, actions) { stream.inc(); } - success; + success == 1; } // Dot @@ -250,9 +254,9 @@ Dot = Object.subtype(#Dot); Dot.match(stream, context, actions) { if (!stream.atEnd()) { stream.inc(); - 1; + true; } else { - 0; + false; } } @@ -262,7 +266,7 @@ Begin = Object.subtype(#Begin); Begin.match(stream, context, actions) { stream.setLastBegin(); - 1; + true; } // End @@ -271,7 +275,7 @@ End = Object.subtype(#End); End.match(stream, context, actions) { context.variables.yytext = stream.content[stream.lastBegin..stream.position].unescaped(); - 1; + true; } // Optional (? postfix operator) @@ -279,18 +283,8 @@ End.match(stream, context, actions) { Optional = Object.subtype(#Optional); Optional.match(stream, context, actions) { - let initialActionCount = actions.length(); - let startingPosition = stream.position; - let success = self.expression.match(stream, context, actions); - - if (success == 0) { - while (actions.length() > initialActionCount) { - actions.pop(); - } - stream.position = startingPosition; - } - - 1; + self.expression.match(stream, context, actions); + true; } // Star @@ -298,8 +292,8 @@ Optional.match(stream, context, actions) { Star = Object.subtype(#Star); Star.match(stream, context, actions) { - while (self.expression.match(stream, context, actions) == 1) {} - 1; + while (self.expression.match(stream, context, actions)) {} + true; } // Plus @@ -307,11 +301,11 @@ Star.match(stream, context, actions) { Plus = Object.subtype(#Plus); Plus.match(stream, context, actions) { - if (self.expression.match(stream, context, actions) == 1) { - while (self.expression.match(stream, context, actions) == 1) {} - 1; + if (self.expression.match(stream, context, actions) == true) { + while (self.expression.match(stream, context, actions) == true) {} + true; } else { - 0; + false; } } @@ -322,11 +316,11 @@ And = Object.subtype(#And); And.match(stream, context, actions) { let position = stream.position; - if (self.expression.match(stream, context, actions) == 1) { + if (self.expression.match(stream, context, actions) == true) { stream.position = position; - 1; + true; } else { - 0; + false; } } @@ -337,11 +331,11 @@ Not = Object.subtype(#Not); Not.match(stream, context, actions) { let position = stream.position; - if (self.expression.match(stream, context, actions) == 1) { + if (self.expression.match(stream, context, actions) == true) { stream.position = position; - 0; + false; } else { - 1; + true; } } @@ -349,38 +343,42 @@ Not.match(stream, context, actions) { Sequence = Object.subtype(#Sequence); +Sequence._match(stream, context, actions, index) { + if (index == self.length() - 1) { + return self[index].match(stream, context, actions); + } + self[index].match(stream, context, actions) && self._match(stream, context, actions, index + 1); +} + Sequence.match(stream, context, actions) { - let i = 0; - let match = 1; - while (i < self.length() && match == 1) { - match = self[i].match(stream, context, actions); - i = i + 1; + let initialActionCount = actions.length(); + let startingPosition = stream.position; + + success = self._match(stream, context, actions, 0); + + if (success == false) { + while (actions.length() > initialActionCount) { + actions.pop(); + } + stream.position = startingPosition; } - match; + + success; } // Alternation Alternation = Object.subtype(#Alternation); -Alternation.match(stream, context, actions) { - let i = 0; - let success = 0; - while (i < self.length() && success == 0) { - let initialActionCount = actions.length(); - let startingPosition = stream.position; - success = self[i].match(stream, context, actions); - - if (success == 0) { - while (actions.length() > initialActionCount) { - actions.pop(); - } - stream.position = startingPosition; - } - - i = i + 1; +Alternation._match(stream, context, actions, index) { + if (index == self.length() - 1) { + return self[index].match(stream, context, actions); } - success; + self[index].match(stream, context, actions) || self._match(stream, context, actions, index + 1); +} + +Alternation.match(stream, context, actions) { + return self._match(stream, context, actions, 0); } // Action @@ -389,7 +387,7 @@ Action = Object.subtype(#Action); Action.match(stream, context, actions) { actions.push([action: self, context: context]); - 1; + true; } Action.execute(context) { @@ -416,9 +414,9 @@ ParseTimeAction = Object.subtype(#ParseTimeAction); ParseTimeAction.match(stream, context, actions) { if(self.action.execute(context)) { - 1; + true; } else { - 0; + false; } } @@ -695,7 +693,7 @@ grammar = Sequence.new() .push(RuleCall.new(name: #ws)) .push(Plus.new(expression: Sequence.new() .push(Assignment.new(name: #d, rule: RuleCall.new(name: #definition))) - .push(Action.new(parseTree: `{ set(d.name, d.expression); print("Parsed rule ", d.name, "\n"); })) + .push(Action.new(parseTree: `{ set(d.name, d.expression); })) )) .push(RuleCall.new(name: #end_of_file)); @@ -963,7 +961,6 @@ ws = Star.new(expression: Alternation.new() with(#reading); - stream = newStream(readfile("rawminproto.leg")); context = Context.new(outerContext: nil).init(); actions = []; diff --git a/minproto.leg b/minproto.leg index a3d47aa..e26999e 100644 --- a/minproto.leg +++ b/minproto.leg @@ -108,9 +108,9 @@ oop printOn(oop buf, oop obj, int indent); #endif #if PRIMCLOSURE -#define doProtos(_) _(Object) _(RefSym) _(GetSym) _(SetSym) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure)_(Raise)_(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Range) +#define doProtos(_) _(Object) _(RefSym) _(GetSym) _(SetSym) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure)_(Raise)_(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Range) _(Stream) #else -#define doProtos(_) _(Object) _(RefSym) _(GetSym) _(SetSym) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure) _(Raise) _(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Lambda) _(Closure) _(Range) +#define doProtos(_) _(Object) _(RefSym) _(GetSym) _(SetSym) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure) _(Raise) _(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Lambda) _(Closure) _(Range) _(Stream) #endif #define declareProto(NAME) oop p##NAME = 0; @@ -134,7 +134,7 @@ doTypes(makeProto); doProperties(declareProp); #undef declareProp -#define doSymbols(_) _(t) _(name) _(expr) _(function) _(arguments) _(object) _(index) _(key) _(value) _(self) _(method) _(parameters) _(body) _(lambda) _(environment) _(operation) _(full) _(condition) _(consequent) _(alternate) _(expression) _(identifier) _(initialise) _(update) _(first) _(last) _(fixed) _(keyvals) _(__namespaces__) _(O) _(d) _(v) _(statement) _(handler) _(kind) _(message) _(operand1) _(operand2) _(start) _(end) _(env) +#define doSymbols(_) _(t) _(name) _(expr) _(function) _(arguments) _(object) _(index) _(key) _(value) _(self) _(method) _(parameters) _(body) _(lambda) _(environment) _(operation) _(full) _(condition) _(consequent) _(alternate) _(expression) _(identifier) _(initialise) _(update) _(first) _(last) _(fixed) _(keyvals) _(__namespaces__) _(O) _(d) _(v) _(statement) _(handler) _(kind) _(message) _(operand1) _(operand2) _(start) _(end) _(env) _(content) _(position) _(limit) _(lastBegin) #define declareSym(NAME) oop sym_##NAME = 0; doSymbols(declareSym); @@ -3102,6 +3102,26 @@ void Literal_codeOn(oop exp, oop str, oop env) # endif } +oop newStream(oop content) +{ + oop o = new(pStream); + Object_put(o, sym_content , content); + Object_put(o, sym_position , newInteger(0)); + Object_put(o, sym_limit , newInteger(_get(content, String, length))); + Object_put(o, sym_lastBegin, newInteger(0)); + return o; +} + +oop Stream_eval(oop exp, oop env) +{ + return exp; +} + +void Stream_codeOn(oop exp, oop str, oop env) +{ + Object_codeOn(exp, str, env); +} + oop lvalue(oop rval) { if (!is(Object,rval)) valueError("=", "non-assignable value", rval); @@ -3765,6 +3785,47 @@ oop prim_Symbol_asString(oop func, oop self, oop args, oop env) return newString(_get(self, Symbol,name)); } + +oop prim_newStream(oop func, oop self, oop args, oop env) +{ assert(is(Object, args)); + int argc = _get(args, Object,isize); + if (argc != 1) fatal("newStream: Expected 1 argument, got %d\n", argc); + oop arg = _get(args, Object, indexed)[0]; + if (!is(String, arg)) fatal("newStream: expected an argument of type String, got type %s instead\n", getType(arg)); + return newStream(arg); +} + +oop prim_Stream_atEnd(oop func, oop self, oop args, oop env) +{ + return newBoolean(_integerValue(Object_get(self, sym_position)) >= _integerValue(Object_get(self, sym_limit))); +} + +oop prim_Stream_inc(oop func, oop self, oop args, oop env) +{ + if (_integerValue(Object_get(self, sym_position)) < _integerValue(Object_get(self, sym_limit))) { + // There has to be a better way of just adding 1 + Object_put(self, sym_position, newInteger(_integerValue(Object_get(self, sym_position)) + 1)); + } + return Object_get(self, sym_position); +} + +oop prim_Stream_setLastBegin(oop func, oop self, oop args, oop env) +{ + return Object_put(self, sym_lastBegin, newInteger(_integerValue(Object_get(self, sym_position)))); +} + +oop prim_Stream_match(oop func, oop self, oop args, oop env) +{ assert(is(Object, args)); + int argc = _get(args, Object,isize); + if (argc != 1) fatal("Stream.match: Expected 1 argument, got %d\n", argc); + oop arg = _get(args, Object, indexed)[0]; assert(is(String, arg)); + return newBoolean(strncmp( + String_content(Object_get(self, sym_content)) + _integerValue(Object_get(self, sym_position)), + String_content(arg), + strlen(String_content(arg)) + ) == 0); +} + oop prim_length(oop func, oop self, oop args, oop env) { assert(is(Object, args)); if (!is(Object, self)) valueError("length", "not an object", self); @@ -4242,6 +4303,7 @@ int main(int argc, char **argv) prim(newApply , prim_newApply); prim(lvalue , prim_lvalue); prim(assign , prim_assign); + prim(newStream , prim_newStream); # undef prim @@ -4274,6 +4336,10 @@ int main(int argc, char **argv) method(Symbol,define, prim_Symbol_define ); method(Symbol,value, prim_Symbol_value ); method(Symbol,allInstances, prim_Symbol_allInstances); + method(Stream,atEnd, prim_Stream_atEnd ); + method(Stream,inc, prim_Stream_inc ); + method(Stream,setLastBegin, prim_Stream_setLastBegin); + method(Stream,match, prim_Stream_match ); # undef method