Procházet zdrojové kódy

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.

MaximeBarniaudy před 11 měsíci
rodič
revize
06f1b199f1
2 změnil soubory, kde provedl 161 přidání a 98 odebrání
  1. +92
    -95
      grammar_parser.meta
  2. +69
    -3
      minproto.leg

+ 92
- 95
grammar_parser.meta Zobrazit soubor

@ -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 = [];

+ 69
- 3
minproto.leg Zobrazit soubor

@ -108,9 +108,9 @@ oop printOn(oop buf, oop obj, int indent);
#endif
#if PRIMCLOSURE
#define doProtos(_) _(Object) _(RefLocal) _(GetLocal) _(SetLocal) _(RefGlobal) _(GetGlobal) _(SetGlobal) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Super) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure)_(Raise)_(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Range)
#define doProtos(_) _(Object) _(RefLocal) _(GetLocal) _(SetLocal) _(RefGlobal) _(GetGlobal) _(SetGlobal) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Super) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure)_(Raise)_(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Range) _(Stream)
#else
#define doProtos(_) _(Object) _(RefLocal) _(GetLocal) _(SetLocal) _(RefGlobal) _(GetGlobal) _(SetGlobal) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Super) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure) _(Raise) _(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Lambda) _(Closure) _(Range)
#define doProtos(_) _(Object) _(RefLocal) _(GetLocal) _(SetLocal) _(RefGlobal) _(GetGlobal) _(SetGlobal) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Super) _(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);
@ -3247,6 +3247,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);
@ -4059,6 +4079,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);
@ -4734,6 +4795,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
@ -4776,6 +4838,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

Načítá se…
Zrušit
Uložit