Browse Source

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.

master
MaximeBarniaudy 11 months ago
parent
commit
d840010b55
2 changed files with 161 additions and 98 deletions
  1. +92
    -95
      grammar_parser.meta
  2. +69
    -3
      minproto.leg

+ 92
- 95
grammar_parser.meta View File

@ -1,5 +1,8 @@
// ----- Utils ----- // ----- Utils -----
true = (1 == 1);
false = (1 == 0);
Object.contains(item) { Object.contains(item) {
for (i in self.length()) { for (i in self.length()) {
if (self[i] == item) { if (self[i] == item) {
@ -109,30 +112,22 @@ Object.subtype(name) { self.new(__name__: name) }
// Input stream // 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.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 // Context
@ -156,27 +151,36 @@ Context.declareVariable(var) {
StringLiteral = Object.subtype(#StringLiteral); 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 // Character Class
CharacterClass = Object.subtype(#CharacterClass); CharacterClass = Object.subtype(#CharacterClass);
@ -240,7 +244,7 @@ CharacterClass.match(stream, context, actions) {
stream.inc(); stream.inc();
} }
success;
success == 1;
} }
// Dot // Dot
@ -250,9 +254,9 @@ Dot = Object.subtype(#Dot);
Dot.match(stream, context, actions) { Dot.match(stream, context, actions) {
if (!stream.atEnd()) { if (!stream.atEnd()) {
stream.inc(); stream.inc();
1;
true;
} else { } else {
0;
false;
} }
} }
@ -262,7 +266,7 @@ Begin = Object.subtype(#Begin);
Begin.match(stream, context, actions) { Begin.match(stream, context, actions) {
stream.setLastBegin(); stream.setLastBegin();
1;
true;
} }
// End // End
@ -271,7 +275,7 @@ End = Object.subtype(#End);
End.match(stream, context, actions) { End.match(stream, context, actions) {
context.variables.yytext = stream.content[stream.lastBegin..stream.position].unescaped(); context.variables.yytext = stream.content[stream.lastBegin..stream.position].unescaped();
1;
true;
} }
// Optional (? postfix operator) // Optional (? postfix operator)
@ -279,18 +283,8 @@ End.match(stream, context, actions) {
Optional = Object.subtype(#Optional); Optional = Object.subtype(#Optional);
Optional.match(stream, context, actions) { 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 // Star
@ -298,8 +292,8 @@ Optional.match(stream, context, actions) {
Star = Object.subtype(#Star); Star = Object.subtype(#Star);
Star.match(stream, context, actions) { Star.match(stream, context, actions) {
while (self.expression.match(stream, context, actions) == 1) {}
1;
while (self.expression.match(stream, context, actions)) {}
true;
} }
// Plus // Plus
@ -307,11 +301,11 @@ Star.match(stream, context, actions) {
Plus = Object.subtype(#Plus); Plus = Object.subtype(#Plus);
Plus.match(stream, context, actions) { 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 { } else {
0;
false;
} }
} }
@ -322,11 +316,11 @@ And = Object.subtype(#And);
And.match(stream, context, actions) { And.match(stream, context, actions) {
let position = stream.position; let position = stream.position;
if (self.expression.match(stream, context, actions) == 1) {
if (self.expression.match(stream, context, actions) == true) {
stream.position = position; stream.position = position;
1;
true;
} else { } else {
0;
false;
} }
} }
@ -337,11 +331,11 @@ Not = Object.subtype(#Not);
Not.match(stream, context, actions) { Not.match(stream, context, actions) {
let position = stream.position; let position = stream.position;
if (self.expression.match(stream, context, actions) == 1) {
if (self.expression.match(stream, context, actions) == true) {
stream.position = position; stream.position = position;
0;
false;
} else { } else {
1;
true;
} }
} }
@ -349,38 +343,42 @@ Not.match(stream, context, actions) {
Sequence = Object.subtype(#Sequence); 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) { 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
Alternation = Object.subtype(#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 // Action
@ -389,7 +387,7 @@ Action = Object.subtype(#Action);
Action.match(stream, context, actions) { Action.match(stream, context, actions) {
actions.push([action: self, context: context]); actions.push([action: self, context: context]);
1;
true;
} }
Action.execute(context) { Action.execute(context) {
@ -416,9 +414,9 @@ ParseTimeAction = Object.subtype(#ParseTimeAction);
ParseTimeAction.match(stream, context, actions) { ParseTimeAction.match(stream, context, actions) {
if(self.action.execute(context)) { if(self.action.execute(context)) {
1;
true;
} else { } else {
0;
false;
} }
} }
@ -695,7 +693,7 @@ grammar = Sequence.new()
.push(RuleCall.new(name: #ws)) .push(RuleCall.new(name: #ws))
.push(Plus.new(expression: Sequence.new() .push(Plus.new(expression: Sequence.new()
.push(Assignment.new(name: #d, rule: RuleCall.new(name: #definition))) .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)); .push(RuleCall.new(name: #end_of_file));
@ -963,7 +961,6 @@ ws = Star.new(expression: Alternation.new()
with(#reading); with(#reading);
stream = newStream(readfile("rawminproto.leg")); stream = newStream(readfile("rawminproto.leg"));
context = Context.new(outerContext: nil).init(); context = Context.new(outerContext: nil).init();
actions = []; actions = [];

+ 69
- 3
minproto.leg View File

@ -121,9 +121,9 @@ oop printOn(oop buf, oop obj, int indent);
#endif #endif
#if PRIMCLOSURE #if PRIMCLOSURE
#define doProtos(_) _(Object) _(RefLocal) _(GetLocal) _(SetLocal) _(RefGlobal) _(GetGlobal) _(SetGlobal) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(GetSlice) _(Call) _(Invoke) _(Super) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure)_(Raise)_(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal)
#define doProtos(_) _(Object) _(RefLocal) _(GetLocal) _(SetLocal) _(RefGlobal) _(GetGlobal) _(SetGlobal) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(GetSlice) _(Call) _(Invoke) _(Super) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure)_(Raise)_(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Stream)
#else #else
#define doProtos(_) _(Object) _(RefLocal) _(GetLocal) _(SetLocal) _(RefGlobal) _(GetGlobal) _(SetGlobal) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(GetSlice) _(Call) _(Invoke) _(Super) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure) _(Raise) _(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Lambda) _(Closure)
#define doProtos(_) _(Object) _(RefLocal) _(GetLocal) _(SetLocal) _(RefGlobal) _(GetGlobal) _(SetGlobal) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(GetSlice) _(Call) _(Invoke) _(Super) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure) _(Raise) _(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Lambda) _(Closure) _(Stream)
#endif #endif
#define declareProto(NAME) oop p##NAME = 0; #define declareProto(NAME) oop p##NAME = 0;
@ -147,7 +147,7 @@ doTypes(makeProto);
doProperties(declareProp); doProperties(declareProp);
#undef 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) _(p) _(v) _(statement) _(handler) _(kind) _(message) _(operand1) _(operand2) _(profile) _(parent) _(count) _(stamp) _(time) _(start) _(stop) _($$) _(yytext) _(yyleng) _(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) _(p) _(v) _(statement) _(handler) _(kind) _(message) _(operand1) _(operand2) _(profile) _(parent) _(count) _(stamp) _(time) _(start) _(stop) _($$) _(yytext) _(yyleng) _(env) _(content) _(position) _(limit) _(lastBegin)
#define declareSym(NAME) oop sym_##NAME = 0; #define declareSym(NAME) oop sym_##NAME = 0;
doSymbols(declareSym); doSymbols(declareSym);
@ -3342,6 +3342,26 @@ void Literal_codeOn(oop exp, oop str, oop env)
# endif # 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) oop lvalue(oop rval)
{ {
if (!is(Object,rval)) valueError("=", "non-assignable value", rval); if (!is(Object,rval)) valueError("=", "non-assignable value", rval);
@ -4272,6 +4292,47 @@ oop prim_Symbol_asString(oop func, oop self, oop args, oop env)
return newString(_get(self, Symbol,name)); 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) oop prim_length(oop func, oop self, oop args, oop env)
{ assert(is(Object, args)); { assert(is(Object, args));
if (!is(Object, self)) valueError("length", "not an object", self); if (!is(Object, self)) valueError("length", "not an object", self);
@ -5456,6 +5517,7 @@ int main(int argc, char **argv)
prim(newApply , prim_newApply); prim(newApply , prim_newApply);
prim(lvalue , prim_lvalue); prim(lvalue , prim_lvalue);
prim(assign , prim_assign); prim(assign , prim_assign);
prim(newStream , prim_newStream);
# undef prim # undef prim
@ -5498,6 +5560,10 @@ int main(int argc, char **argv)
method(Symbol,define, prim_Symbol_define ); method(Symbol,define, prim_Symbol_define );
method(Symbol,value, prim_Symbol_value ); method(Symbol,value, prim_Symbol_value );
method(Symbol,allInstances, prim_Symbol_allInstances); 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 # undef method

Loading…
Cancel
Save