public static int Main(string[] args) { if (args.Length == 3) { var name = args[0]; var input = args[1]; var output = args[2]; var root = new ast.Define(); root.identity = new ast.Identity(); root.identity.name = "root"; var worker = new ast.Worker(root); var scanner = new coco.Scanner(input); var parser = new coco.Parser(scanner); parser.worker = worker; parser.Parse(); if (parser.errors.count == 0) { var printer = new Printer(root); printer.Write(name, output); } Console.WriteLine(parser.errors.count + " errors detected"); return(parser.errors.count); } else { Console.WriteLine("name, input and output filename expected"); return(-1); } }
bool Accept(Define define, Cache cache) { if (define.identity.val == cache.part.identity.val) { cache.Watch(define); if (define.paramList.Count == cache.part.paramList.Count) { var clone = false; for (var i = 0; i < define.paramList.Count; i++) { var keyLink = cache.part.paramList[i]; var holeLink = define.paramList[i].link; var key = keyLink.Find(cache.from).Type; var hole = holeLink.Find(define).Type; if (keyLink.Level != holeLink.Level) { return(false); } while (key != hole) { if (key == nil) { return(false); } key = key.link.Find(key).Type; clone = true; } } cache.part.Bind(define, clone); return(true); } } return(false); }
void AddOps(Define root, Define define, Final boolean) { var final = new Final(define); root.fieldList.Add(define); root.fieldList.Add(Define.BuiltIn("+", final, final)); root.fieldList.Add(Define.BuiltIn("<<", final, final)); root.fieldList.Add(Define.BuiltIn(">>", final, final)); root.fieldList.Add(Define.BuiltIn("<", final, boolean)); root.fieldList.Add(Define.BuiltIn(">", final, boolean)); root.fieldList.Add(Define.BuiltIn("<=", final, boolean)); root.fieldList.Add(Define.BuiltIn(">=", final, boolean)); if (define != Define.unicode) { if (define != Define.float8 && define != Define.float12) { root.fieldList.Add(Define.BuiltIn("&", final, final)); root.fieldList.Add(Define.BuiltIn("|", final, final)); root.fieldList.Add(Define.BuiltIn("^", final, final)); root.fieldList.Add(Define.BuiltIn("%", final, final)); } root.fieldList.Add(Define.BuiltIn("*", final, final)); root.fieldList.Add(Define.BuiltIn("/", final, final)); root.fieldList.Add(Define.BuiltIn("-", final, final)); } }
bool Accept(ast.Part part, ast.Define define) { if (part.identity.name == define.identity.name) { var leaf = Enter(define); Trace(); var success = (part.paramList.Count == define.paramList.Count); for (var i = 0; success && i < part.paramList.Count; i++) { var key = context.EvaluateNode(part.paramList[i]); var hole = EvaluateNode(define.paramList[i].node); success = key.Type() == hole.Type(); while (!success && key is Solver) { var super = key as Solver; key = super.EvaluateNode(super.Leaf.node); success = key.Type() == hole.Type(); } } if (success) { return(true); } Leave(leaf); } return(false); }
public void Write(ast.Define root, string output) { try { clang.Open(output + ".c"); clang.Put(clang.finalDef); WriteTypeFamily(root); clang.Begin(clang.fieldDef) .Put(root.Type.Name) .Put(root.Name); WriteCopyFamily(root); WriteCallFamily(root); clang.Begin(clang.mainDef) .Put(root.Type.Name); clang.Close(); } catch (Exception exception) { clang.Delete(); Console.Out.WriteLine(exception.Message + "\nStack Trace:\n" + exception.StackTrace); } finally { clang.Dispose(); } }
void WriteCopy(ast.Define define) { var format = clang.Begin(clang.copyDef); format.Put(define.Type.Name); format.Put(define.Type.Name); format.Put(define.Type.Name); clang.Enter(); if (define.NeedThat) { clang.Begin(clang.finalCopy) .Put(define.that.Name) .Put(define.that.Name); } if (define.link.Tail != ast.Define.nil) { WriteCopyField(define.link.Tail); } foreach (var field in define.fieldList) { if (!field.IsCall && field.IsReferred && field.IsPrintable) { WriteCopyField(field); } } foreach (var clone in define.cloneList) { if (!clone.IsCall && clone.IsReferred && clone.IsPrintable) { WriteCopyField(clone); } } clang.Leave(); format.End(); }
public void Watch(Define candidate) { if (candidateList == DefineList.none) { candidateList = new DefineList(); } candidateList.Add(candidate); }
public static Define Final(string name) { var define = new Define(); define.identity = new Identity(name); define.flag = FINAL; return(define); }
public static Define BuiltIn(string name) { var define = new Define(); define.identity = new Identity(name); define.flag = BUILTIN; return(define); }
public static Define Root(string name) { var define = new Define(); define.identity = new Identity(name); define.flag = REFERRED; return(define); }
void WriteCall(ast.Define define) { var format = clang.Begin(clang.callDef); format.Put(define.Call.Name); if (!define.IsRoot) { clang.Begin(clang.firstParamDef) .Put(define.Type.Name) .Put(define.Name); } format.Put(); if (define.NeedThat) { clang.Begin(clang.typeNextParamDef) .Put(define.that.Type.Name) .Put(define.that.Name); } foreach (var param in define.paramList) { if (param.IsFinal) { clang.Begin(clang.finalNextParamDef) .Put(param.Type.Name) .Put(param.Name); } else { clang.Begin(clang.typeNextParamDef) .Put(param.Type.Name) .Put(param.Name); } } format.Put(); clang.Enter(); if (define.IsType && define.NeedThat) { clang.Begin(clang.thatCall) .Put(define.Name) .Put(define.that.Name) .Put(define.that.Name); } if (define.link.Tail != ast.Define.nil) { WriteCallField(define.link.Tail, define.link, define); } foreach (var field in define.fieldList) { WriteCallField(field, define); } foreach (var clone in define.cloneList) { WriteCallField(clone, define); } clang.Leave(); format.End(); }
public void Enter(Define define) { var that = list[list.Count - 1]; if (that.fieldList == DefineList.none) { that.fieldList = new DefineList(); } that.fieldList.Add(define); list.Add(define); }
public void Leave(Define define) { if (0 != (define.flag & ast.Define.PARAM)) { list[list.Count - 1] = define; } else { list.RemoveAt(list.Count - 1); } }
public Define Clone() { var define = new Define(); define.identity = identity.Clone(); define.paramList = paramList.Clone(); define.link = link.Clone(); define.fieldList = fieldList.Clone(); define.that = that; define.flag = flag; return(define); }
void WriteCallTail(ast.Define define, ast.Define from, ast.Part part, List <Route> paramList) { if (define.IsReferred) { if (part.define.IsBuiltIn) { clang.Begin(clang.opTailCall) .Put(NameFinal(define, from)) .Put(paramList[0].Value) .Put(part.define.identity.val) .Put(paramList[1].Value); } else { var format = clang.Begin(clang.typeTailCall); format.Put(define.Call.Name); format.Put(NameType(define, from)); foreach (var param in paramList) { clang.Begin(clang.paramCall).Put(param.Param); } format.End(); } } else { if (part.define.IsBuiltIn) { clang.Begin(clang.opLocalCall) .Put(define.Type.Name) .Put(define.Name) .Put(paramList[0].Value) .Put(part.define.identity.val) .Put(paramList[1].Value); } else { var format = clang.Begin(clang.typeLocalCall); format.Put(define.Type.Name); format.Put(define.Name); format.Put(define.Call.Name); format.Put(define.Name); foreach (var param in paramList) { clang.Begin(clang.paramCall).Put(param.Param); } format.End(); } } }
public void Evaluate(Define that) { this.that = that; foreach (var param in paramList) { param.flag |= PARAM; param.Evaluate(that); } link.Find(this); foreach (var field in fieldList) { field.Evaluate(this); } }
public Define Enter(Define define) { var leaf = list[list.Count - 1]; if (0 != (define.flag & ast.Define.PARAM)) { list[list.Count - 1] = define; } else { list.Add(define); } return(leaf); }
void WriteTypeFamily(ast.Define define) { foreach (var field in define.fieldList) { WriteTypeFamily(field); } foreach (var clone in define.cloneList) { WriteTypeFamily(clone); } if (define.IsType && define.IsReferred && define.IsPrintable) { WriteType(define); } }
void WriteCopyFamily(ast.Define define) { foreach (var field in define.fieldList) { WriteCopyFamily(field); } foreach (var clone in define.cloneList) { WriteCopyFamily(clone); } if (define.IsType && define.NeedCopy) { WriteCopy(define); } }
public Route(ast.Define that, ast.Define from) { var it = from != that ? from.that : from; value = it.Name; while (it != that) { it = it.that; value += "->" + it.Name; } level = 1; final = false; }
string NameFinal(ast.Define define, ast.Define from) { if (!from.IsType) { return("*" + from.Name); } else if (from.IsRoot) { return(from.Name + "." + define.Name); } else { return(from.Name + "->" + define.Name); } }
void WriteCopyField(ast.Define define) { if (define.IsFinal) { clang.Begin(clang.finalCopy) .Put(define.Name) .Put(define.Name); } else { clang.Begin(clang.typeCopy) .Put(define.Type.Name) .Put(define.Name) .Put(define.Name); } }
void WriteCallField(ast.Define field, ast.Define define) { if (field.IsSnapped) { clang.Begin(clang.label).Put(field.Name); } if (!field.IsCall && field.IsPrintable) { if (field.IsType && !field.IsSpecial) { if (field.NeedThat) { clang.Begin(clang.typeWithThatCall) .Put(field.Name) .Put(NameType(field, define)) .Put(define.Name); } else { clang.Begin(clang.typeCall) .Put(field.Name) .Put(NameType(field, define)); } } else { WriteCallField(field, field.link, define); if (field.IsCase) { var format = clang.Begin(clang.caseBlock); format.Put(field.Name); clang.Enter(); foreach (var local in field.fieldList) { WriteCallField(local, define); } foreach (var clone in field.cloneList) { WriteCallField(clone, define); } clang.Leave(); format.End(); } } } }
public Worker(Define root) { var boolean = new Final(Define.boolean); root.fieldList = new DefineList(); root.fieldList.Add(Define.nil); AddOps(root, Define.boolean, boolean); AddOps(root, Define.int1, boolean); AddOps(root, Define.int2, boolean); AddOps(root, Define.int4, boolean); AddOps(root, Define.int8, boolean); AddOps(root, Define.uint1, boolean); AddOps(root, Define.uint2, boolean); AddOps(root, Define.uint4, boolean); AddOps(root, Define.uint8, boolean); AddOps(root, Define.float8, boolean); AddOps(root, Define.float12, boolean); AddOps(root, Define.unicode, boolean); list.Add(root); }
void WriteType(ast.Define define) { var format = clang.Begin(clang.typeDef); format.Put(define.Name); clang.Enter(); if (define.NeedThat) { clang.Begin(clang.thatDef) .Put(define.that.Type.Name) .Put(define.that.Name); } if (define.link.Tail != ast.Define.nil) { clang.Begin(clang.fieldDef) .Put(define.link.Tail.Type.Name) .Put(define.link.Tail.Name); } foreach (var field in define.fieldList) { if (!field.IsCall && field.IsReferred && field.IsPrintable) { clang.Begin(clang.fieldDef) .Put(field.Type.Name) .Put(field.Name); } } foreach (var clone in define.cloneList) { if (!clone.IsCall && clone.IsReferred && clone.IsPrintable) { clang.Begin(clang.fieldDef) .Put(clone.Type.Name) .Put(clone.Name); } } clang.Leave(); format.Put(); format.Put(define.Name); format.Put(define.Type.Name); }
void WriteCallFamily(ast.Define define) { foreach (var field in define.fieldList) { if (field.IsPrintable) { WriteCallFamily(field); } } foreach (var clone in define.cloneList) { if (clone.IsPrintable) { WriteCallFamily(clone); } } if ((define.IsCall || define.IsType) && define.IsReferred && define.IsPrintable) { WriteCall(define); } }
public void Bind(Define accept, bool clone) { level += accept.Level; if (clone && (accept.flag & Define.BUILTIN) == 0) { define = accept.Clone(); for (var i = 0; i < paramList.Count; i++) { define.paramList[i].link = paramList[i]; } if (define.that.cloneList == DefineList.none) { define.that.cloneList = new DefineList(); } define.that.cloneList.Add(define); define.Evaluate(define.that); } else { define = accept; } }
void WriteCallTail(ast.Define define, ast.Define from, Route route) { if (define.IsReferred) { if (define.IsFinal) { clang.Begin(clang.finalTailCall) .Put(NameFinal(define, from)) .Put(route.Value); } else { clang.Begin(clang.typeCopyCall) .Put(define.Type.Name) .Put(NameType(define, from)) .Put(route.Address); } } else { if (define.IsFinal) { clang.Begin(clang.finalLocalCall) .Put(define.Type.Name) .Put(define.Name) .Put(route.Value); } else { clang.Begin(clang.typeLocalCopyCall) .Put(define.Type.Name) .Put(define.Name) .Put(define.Type.Name) .Put(define.Name) .Put(route.Address); } } }
bool EvaluatePart(ast.Part part) { if (Accept(part)) { if (Leaf.paramList != ast.DefineList.nil) { var clone = new ast.Define(); clone.identity = part.identity; clone.paramList = new ast.DefineList(); for (var i = 0; i < Leaf.paramList.Count; i++) { var param = new ast.Define(); param.identity = Leaf.paramList[i].identity; param.node = context.EvaluateNode(part.paramList[i]); clone.paramList.Add(param); } clone.node = Leaf.node; clone.childList = Leaf.childList; Leaf = clone; } return(true); } return(false); }
public void Add(Define define) { var leaf = scope.Leaf; var found = leaf.childList.FindLast(element => element.identity.name == define.identity.name); if (found == null) { define.unique = 0; } else { if (found.unique == 0) { found.unique = 1; } define.unique = found.unique + 1; } if (leaf.childList == DefineList.nil) { leaf.childList = new DefineList(); } leaf.childList.Add(define); scope.Add(define); }