private void CompileClauseHead(PrologCodeTerm head, ArrayList instructions) { if (head is PrologCodePredicate) { PrologCodePredicate headPredicate = (PrologCodePredicate)head; if (headPredicate.Arity == 0) { /* Do nothing */ } else { CompileHeadArguments(((PrologCodePredicate)head).Arguments); } } else if (head is PrologCodeNonEmptyList) { ArrayList headListArguments = new ArrayList(); PrologCodeNonEmptyList NEList = (PrologCodeNonEmptyList)head; headListArguments.Add(NEList.Head); headListArguments.Add(NEList.Tail); CompileHeadArguments(headListArguments); } else if (head is PrologCodeVariable) { throw new PrologCompilerException("Clause head cannot be a variable."); } else if (head is PrologCodeIntegerAtom || head is PrologCodeFloatAtom) { throw new PrologCompilerException("Clause head cannot be a number."); } }
private void ProcessAssemblyDirective(PrologCodePredicate pred) { string asm = ((PrologCodeStringAtom)pred.Arguments[0]).Value; asm = asm.Replace("'", ""); _codeUnit.AssemblyFiles.Add(asm); }
private bool ResolveConflicts(PrologCodeTerm term, int index) { PrologVariableDictionaryEntry entry = _dictionary.GetVariable(index); if (_dictionary.CurrentGoalIndex != 1 || entry == null || entry.LastGoalArgument < index) { PrologRegisterTable.Instance.AllocateRegister(index); return(false); } if (term is PrologCodePredicate) { PrologCodePredicate predicate = (PrologCodePredicate)term; for (int i = index + 1; i < entry.LastGoalArgument; i++) { if (predicate.Name == entry.Name && (_dictionary.GetVariable(i) == null || ResolveConflicts(term, i))) { entry.TemporaryIndex = i; _generator.Emit(OpCodes.Put_Value, X(index), X(i)); return(true); } } // I WAS HERE } //return true; THIS WAS THERE entry.TemporaryIndex = PrologRegisterTable.Instance.FindRegister(); _generator.Emit(OpCodes.Put_Value, X(index), X(entry.TemporaryIndex)); return(true); }
private void ProcessUsingDirective(PrologCodePredicate pred) { string ns = ((PrologCodeStringAtom)pred.Arguments[0]).Value; ns = ns.Replace("'", ""); _codeUnit.Namespaces.Add(ns); }
/* Initialize temporary goal variables in the dictionary */ private void InitializeGoalTemporaryVariables(PrologCodeTerm goal) { /* Free all registers */ PrologRegisterTable.Instance.FreeAllRegisters(); int reg = 0; if (goal is PrologCodePredicate) { PrologCodePredicate g = (PrologCodePredicate)goal; if (g.Arity > 0) { foreach (PrologCodeTerm var in g.Arguments) { if (var is PrologCodeVariable) { PrologVariableDictionaryEntry entry = _dictionary.GetVariable(((PrologCodeVariable)var).Name); if (entry != null) { if (entry.IsTemporary && entry.TemporaryIndex == -1) { _dictionary.AllocateTemporaryVariable(entry, reg); } } reg++; } } } } }
private void AddGoalStructArgumentVariables(PrologCodeTerm term) { if (PrologCodeTerm.IsAtom(term)) { return; } else if (PrologCodeTerm.IsVariable(term)) { this.Add(((PrologCodeVariable)term).Name, null); } else if (PrologCodeTerm.IsList(term)) { if (term is PrologCodeNonEmptyList) { PrologCodeNonEmptyList list = (PrologCodeNonEmptyList)term; AddGoalStructArgumentVariables(list.Head); if (list.Tail is PrologCodeNonEmptyList) { AddGoalStructArgumentVariables(list.Tail); } else { AddGoalStructArgumentVariables(list.Tail); } } } else if (PrologCodeTerm.IsStruct(term)) { PrologCodePredicate structure = (PrologCodePredicate)term; foreach (PrologCodeTerm argument in structure.Arguments) { AddGoalStructArgumentVariables(argument); } } }
private PrologCodeTerm ConvertGoalBinaryTreeToCodeDOM(BinaryTree goal) { if (goal.Name == ".") { return(ConvertBinaryListToCodeDOM(goal)); } else if (Char.IsUpper(goal.Name[0])) // Goal is a variable { return(new PrologCodeVariable(goal.Name)); } else { PrologCodePredicate goalPredicate = new PrologCodePredicate(goal.Name); ArrayList gargs = new ArrayList(); goal.Flatten(goal, ref gargs); goalPredicate.IsMethod = IsMethod(goal.Name, gargs.Count); goalPredicate.MethodInfo = GetMethodInfo(goal.Name); if (goal.Arguments != null && goal.Arguments.Count != 0) { // Example: // goal(X,a). ArrayList arguments = new ArrayList(); goal.Flatten((BinaryTree)goal.Arguments[0], ref arguments); foreach (BinaryTree a in arguments) { goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(a)); } return(goalPredicate); } else { // X = a (goal is '=') if (goal.Left != null && goal.Right != null) { goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(goal.Left)); goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(goal.Right)); return(goalPredicate); } // [] + foo. if (goal.Left == null && goal.Right != null) { goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(goal.Right)); return(goalPredicate); } // X + [] if (goal.Left != null && goal.Right == null) { goalPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(goal.Left)); return(goalPredicate); } if (goal.Left == null && goal.Right == null) { return(goalPredicate); } } } return(null); }
public void NameTest() { PrologCodePredicate prologCodePredicate = new PrologCodePredicate("male"); string result = prologCodePredicate.Name; Assert.AreEqual("male", result); }
public void ArgumentsTest() { PrologCodePredicate prologCodePredicate = new PrologCodePredicate("predicate"); ArrayList result = prologCodePredicate.Arguments; Assert.AreEqual(0, result.Count); }
public void ArityTest() { PrologCodePredicate prologCodePredicate = new PrologCodePredicate(); int result = prologCodePredicate.Arity; Assert.AreEqual(0, result); }
public void HeadTest() { PrologCodePredicate head = new PrologCodePredicate("head"); PrologCodeNonEmptyList prologCodeNonEmptyList = new PrologCodeNonEmptyList(head); object result = prologCodeNonEmptyList.Head; Assert.AreEqual(head, result); }
private void CompileGoal(PrologCodeTerm goal, ArrayList instructions) { if (goal is PrologCodePredicate && ((PrologCodePredicate)goal).Arity == 0) { PrologCodePredicate goalPredicate = (PrologCodePredicate)goal; if (goalPredicate.Arity == 0) { if (goalPredicate.Name == "!") { _generator.Emit(OpCodes.Cut); if (_dictionary.InLastGoal) { _generator.Emit(OpCodes.Deallocate); _generator.EndProcedure(); } return; } if (goalPredicate.Name == "fail") { _generator.Emit(OpCodes.Fail); _generator.EndProcedure(); return; } // TODO: handle methods here... CompileCall(goalPredicate); } } else if (goal is PrologCodeVariable) { CompileGoalVariable((PrologCodeVariable)goal, 0); if (_dictionary.InLastGoal) { if (_dictionary.CurrentGoalIndex > 1) { _generator.Emit(OpCodes.Deallocate); } _generator.EmitExecuteVar(((PrologCodeVariable)goal).Name, 0); } else { _generator.EmitCallVar(((PrologCodeVariable)goal).Name, 0); } } else if (goal is PrologCodeNonEmptyList) { // TODO: compile list arguments, then call ./2 } else if (goal is PrologCodeIntegerAtom || goal is PrologCodeFloatAtom) { throw new PrologCompilerException("Clause goal cannot be a number."); } else if (goal is PrologCodePredicate) { CompileGoalArguments(((PrologCodePredicate)goal).Arguments); CompileCall(goal); } }
private void ProcessHeadlessClause(PrologCodeTerm term) { PrologCodeHeadlessClause clause = (PrologCodeHeadlessClause)term; foreach (PrologCodeTerm t in clause.Goals) { if (t is PrologCodePredicate) { PrologCodePredicate pred = (PrologCodePredicate)t; switch (pred.Name) { case "op": ProcessOperator(pred); break; case "class": PrologCodeTerm arg = (PrologCodeTerm)pred.Arguments[0]; if (arg is PrologCodeConstantAtom) { PrologCodeConstantAtom atom = (PrologCodeConstantAtom)arg; _codeUnit.Class = atom.Value; } else if (arg is PrologCodeStringAtom) { PrologCodeStringAtom atom = (PrologCodeStringAtom)arg; _codeUnit.Class = atom.Value.Replace("'", ""); } else { _errors.Add(new PrologCompilerError("P0002", "Illegal class name.", "", false, _scanner.Current.Line, _scanner.Current.Column)); } break; case "foreign": ProcessForeignMethod(pred); break; case "load_assembly": ProcessAssemblyDirective(pred); break; case "using": ProcessUsingDirective(pred); break; } } else if (t is PrologCodeList) { } } }
private void CompilePrologPredicateCall(PrologCodePredicate p) { if (_dictionary.InLastGoal) { if (_dictionary.GoalCount > 2) { _generator.Emit(OpCodes.Deallocate); } _generator.EmitExecute(p.Name, p.Arity); } else { _generator.EmitCall(p.Name, p.Arity); } }
private void AddGoalVariables(PrologCodeTerm term) { // no variables to add: predicate/0 if (PrologCodeTerm.IsAtom(term) || PrologCodeTerm.IsAtomicPredicate(term)) { return; } // goal is a variable X else if (PrologCodeTerm.IsVariable(term)) { _currentArgumentIndex = 0; this.Add(((PrologCodeVariable)term).Name, null); return; } // goal is a list, [Term|Term] else if (PrologCodeTerm.IsList(term)) { _currentArgumentIndex = 0; if (term is PrologCodeNonEmptyList) { PrologCodeNonEmptyList list = (PrologCodeNonEmptyList)term; AddGoalArgumentVariables(list.Head); _currentArgumentIndex = 1; if (list.Tail != null) { if (list.Tail is PrologCodeNonEmptyList) { AddGoalArgumentVariables(list.Tail); } else { AddGoalArgumentVariables(list.Tail); } } } } // Goal is a predicate, term(term,...) else if (PrologCodeTerm.IsStruct(term)) { _currentArgumentIndex = 0; PrologCodePredicate goal = (PrologCodePredicate)term; foreach (PrologCodeTerm argument in goal.Arguments) { AddGoalArgumentVariables(argument); _currentArgumentIndex++; } } }
private void CompileBuiltinPredicateCall(PrologCodePredicate p) { AMPredicateSet pset = AMPredicateSet.Instance; _generator.EmitBCall((IAbstractMachinePredicate)pset.CreatePredicate(p.Name, p.Arity)); if (_dictionary.InLastGoal) { if (_dictionary.GoalCount > 2) { _generator.Emit(OpCodes.Deallocate); } // Emit 'proceed' _generator.EndProcedure(); } }
private void CompileCall(PrologCodeTerm p) { AMPredicateSet builtins = AMPredicateSet.Instance; PrologCodePredicate predicate = (PrologCodePredicate)p; if (builtins.IsBuiltin(predicate.Name, predicate.Arity)) { CompileBuiltinPredicateCall(predicate); } else if (predicate.IsMethod) { CompileMethod(predicate); } else { CompilePrologPredicateCall(predicate); } }
private void CompileMethod(PrologCodeTerm method) { PrologCodePredicate predicate = (PrologCodePredicate)method; _generator.EmitFCall(predicate.MethodInfo.PredicateName, predicate.MethodInfo.MethodName, predicate.MethodInfo.AssemblyName, predicate.MethodInfo.Class); if (_dictionary.InLastGoal) { if (_dictionary.GoalCount > 2) { _generator.Emit(OpCodes.Deallocate); } // Emit 'proceed' _generator.EndProcedure(); } }
private void ProcessForeignMethod(PrologCodePredicate p) { // :- foreign(functor(+term,...),'Assembly','Class','MethodName'). PrologCodeMethod foreignMethod = new PrologCodeMethod(); PrologCodePredicate predicateFunctor = (PrologCodePredicate)p.Arguments[0]; // Add argument types foreignMethod.Arguments = GetForeignMethodArguments(predicateFunctor); foreignMethod.AssemblyName = GetAtomOrStringValue((PrologCodeTerm)p.Arguments[1]); foreignMethod.Class = GetAtomOrStringValue((PrologCodeTerm)p.Arguments[2]); foreignMethod.PredicateName = predicateFunctor.Name; foreignMethod.MethodName = predicateFunctor.Name.Replace("'", ""); if (p.Arguments.Count == 4) { foreignMethod.MethodName = GetAtomOrStringValue((PrologCodeTerm)p.Arguments[3]); } // Add the method _codeUnit.Methods.Add(foreignMethod); }
private void ProcessOperator(PrologCodePredicate p) { if (!(p.Arguments[0] is PrologCodeIntegerAtom)) { _errors.Add(new PrologCompilerError("P0009", "Invalid operator priority.", "", false, _scanner.Current.Line, _scanner.Current.Column)); } int priority = ((PrologCodeIntegerAtom)p.Arguments[0]).Value; if (!(p.Arguments[1] is PrologCodeConstantAtom)) { _errors.Add(new PrologCompilerError("P0010", "Invalid operator associativity specifier.", "", false, _scanner.Current.Line, _scanner.Current.Column)); } string associativity = ((PrologCodeConstantAtom)p.Arguments[1]).Value; if (p.Arguments[2] is PrologCodeNonEmptyList) { ArrayList operators = GetListOperators((PrologCodeNonEmptyList)p.Arguments[2]); foreach (PrologCodeTerm op in operators) { DefineNewOperator(priority, associativity, op); } } else if (p.Arguments[2] is PrologCodeConstantAtom) { DefineNewOperator(priority, associativity, (PrologCodeTerm)p.Arguments[2]); } else if (p.Arguments[2] is PrologCodeStringAtom) { DefineNewOperator(priority, associativity, (PrologCodeTerm)p.Arguments[2]); } else { _errors.Add(new PrologCompilerError("P0011", "Invalid operator definition.", "", false, _scanner.Current.Line, _scanner.Current.Column)); } }
private int CompileGoalRecord(PrologCodeTerm term, int index) { ArrayList recs = new ArrayList(); int nRecs = 0; ArrayList arguments = new ArrayList(); if (term is PrologCodeNonEmptyList) { PrologCodeNonEmptyList NEList = (PrologCodeNonEmptyList)term; arguments.Add(NEList.Head); arguments.Add(NEList.Tail); } else if (term is PrologCodePredicate) { arguments = ((PrologCodePredicate)term).Arguments; } for (int i = 0; i < arguments.Count; i++) { PrologCodeTerm r = (PrologCodeTerm)arguments[i]; if (r is PrologCodeNonEmptyList || r is PrologCodePredicate) { nRecs = recs.Add(CompileGoalRecord(r, -1)); } } if (index == -1) { index = PrologRegisterTable.Instance.FindRegister(); } if (term is PrologCodeNonEmptyList) { _generator.Emit(OpCodes.Put_List, X(index)); } else if (term is PrologCodePredicate) { PrologCodePredicate s = (PrologCodePredicate)term; _generator.Emit(OpCodes.Put_Structure, s.Name + "/" + s.Arity, X(index)); } nRecs = 0; for (int i = 0; i < arguments.Count; i++) { PrologCodeTerm t = (PrologCodeTerm)arguments[i]; if (t is PrologCodeNilAtom || t is PrologCodeEmptyList) { _generator.Emit(OpCodes.Set_Constant, "[]"); } else if (t is PrologCodeAtom) { if (t is PrologCodeConstantAtom) { _generator.Emit(OpCodes.Set_Constant, ((PrologCodeConstantAtom)t).Value); } else if (t is PrologCodeStringAtom) { _generator.Emit(OpCodes.Set_Constant, ((PrologCodeStringAtom)t).Value); } else if (t is PrologCodeIntegerAtom) { _generator.Emit(OpCodes.Set_Constant, ((PrologCodeIntegerAtom)t).Value.ToString()); } else if (t is PrologCodeFloatAtom) { _generator.Emit(OpCodes.Set_Constant, ((PrologCodeFloatAtom)t).Value.ToString()); } } else if (t is PrologCodeVariable) { /* Compile Goal record variable */ CompileGoalRecordVariable((PrologCodeVariable)t); } else if (t is PrologCodePredicate || t is PrologCodeNonEmptyList) { _generator.Emit(OpCodes.Set_Value, X((int)recs[nRecs])); PrologRegisterTable.Instance.FreeRegister((int)recs[nRecs]); nRecs++; } } return(index); }
private ArrayList GetForeignMethodArguments(PrologCodePredicate f) { ArrayList args = new ArrayList(); if (f.Arguments[0] is PrologCodeConstantAtom) { PrologCodeConstantAtom fc = (PrologCodeConstantAtom)f.Arguments[0]; if (fc.Value == "none") { return(args); } else { _errors.Add(new PrologCompilerError("P0012", "Invalid predicate-method definition", "", false, _scanner.Current.Line, _scanner.Current.Column)); return(args); } } PrologCodePredicate functor = (PrologCodePredicate)f; foreach (PrologCodePredicate a in functor.Arguments) { int passing = 0; int datatype = 0; switch (a.Name) { case "+": passing = PrologCodeMethodArgument.PASS_IN; break; case "-": passing = PrologCodeMethodArgument.PASS_OUT; break; case "?": passing = PrologCodeMethodArgument.PASS_INOUT; break; default: break; } switch (((PrologCodeConstantAtom)a.Arguments[0]).Value) { case "string": datatype = PrologCodeMethodArgument.STRING; break; case "char": datatype = PrologCodeMethodArgument.CHAR; break; case "int": datatype = PrologCodeMethodArgument.INT; break; case "float": datatype = PrologCodeMethodArgument.FLOAT; break; case "term": datatype = PrologCodeMethodArgument.TERM; break; case "bool": datatype = PrologCodeMethodArgument.BOOL; break; default: break; } args.Add(new PrologCodeMethodArgument(datatype, passing)); } return(args); }
private void CompileHeadArguments(ArrayList arguments) { for (int i = 0; i < arguments.Count; i++) { _currArgN = i; PrologCodeTerm arg = (PrologCodeTerm)arguments[i]; if (arg is PrologCodeNilAtom || arg is PrologCodeEmptyList) { _generator.Emit(OpCodes.Get_Constant, "[]", X(i)); } else if (arg is PrologCodeAtom) { if (arg is PrologCodeConstantAtom) { _generator.Emit(OpCodes.Get_Constant, ((PrologCodeConstantAtom)arg).Value, X(i)); } else if (arg is PrologCodeIntegerAtom) { _generator.Emit(OpCodes.Get_Constant, ((PrologCodeIntegerAtom)arg).Value.ToString(), X(i)); } else if (arg is PrologCodeFloatAtom) { _generator.Emit(OpCodes.Get_Constant, ((PrologCodeFloatAtom)arg).Value.ToString(), X(i)); } else if (arg is PrologCodeStringAtom) { _generator.Emit(OpCodes.Get_Constant, ((PrologCodeStringAtom)arg).Value, X(i)); } } else if (arg is PrologCodeVariable) { if (_dictionary.GoalCount == 0) { // warning: singleton variable } PrologVariableDictionaryEntry entry = _dictionary.GetVariable(((PrologCodeVariable)arg).Name); if (entry.IsTemporary) { if (entry.IsReferenced && entry.TemporaryIndex != i) { _generator.Emit(OpCodes.Get_Value, X(entry.TemporaryIndex), X(i)); } } else { if (entry.IsReferenced) { _generator.Emit(OpCodes.Get_Value, Y(entry.PermanentIndex), X(i)); } else { _generator.Emit(OpCodes.Get_Variable, Y(entry.PermanentIndex), X(i)); } } } else if (arg is PrologCodeNonEmptyList) { _generator.Emit(OpCodes.Get_List, X(i)); ArrayList listArguments = new ArrayList(); PrologCodeNonEmptyList NEList = (PrologCodeNonEmptyList)arg; listArguments.Add(NEList.Head); listArguments.Add(NEList.Tail); CompileStructArguments(listArguments); } else if (arg is PrologCodePredicate) { PrologCodePredicate structure = (PrologCodePredicate)arg; _generator.Emit(OpCodes.Get_Structure, structure.Name + "/" + structure.Arity, X(i)); CompileStructArguments(structure.Arguments); } else { throw new PrologCompilerException("Unknown argument type (" + arg.GetType().ToString() + ") in head arguments"); } } }
public void GenerateCodeFromPredicate(PrologCodePredicate p, ArrayList a) { PrologCodeClause clause = new PrologCodeClause(p); GenerateCodeFromClause(clause, a); }
public void GenerateCodeFromClause(PrologCodeClause clause, ArrayList instructions) { /* Do we need to allocate an environment? */ bool hasEnvironment = clause.Goals.Count > 1; /* Initialize variable dictionary */ _dictionary = new PrologVariableDictionary(); /* Build the variable dictionary for this clause */ _dictionary.Build(clause); /* Free all registers */ PrologRegisterTable registers = PrologRegisterTable.Instance; registers.FreeAllRegisters(); /* Prepare head variables for code generation */ int reg = 0; if (clause.Head.Arity > 0) { headArity = clause.Head.Arity; foreach (PrologCodeTerm argument in clause.Head.Arguments) { if (argument is PrologCodeVariable) { PrologCodeVariable var = (PrologCodeVariable)argument; PrologVariableDictionaryEntry entry = _dictionary.GetVariable(var.Name); if (entry != null) { if (entry.IsTemporary && entry.TemporaryIndex == -1) { entry.IsReferenced = true; _dictionary.AllocateTemporaryVariable(entry, reg); } } //BUG: reg++; } reg++; } } /* Prepare first goal variables */ int xreg = 0; PrologCodeTerm fg = null; if (clause.Goals.Count > 0) { fg = (PrologCodeTerm)clause.Goals[0]; } if (fg is PrologCodePredicate) { PrologCodePredicate firstGoal = (PrologCodePredicate)fg; if (firstGoal.Name == "!") { hasEnvironment = true; } if (firstGoal.Arity > 0) { foreach (PrologCodeTerm variable in firstGoal.Arguments) { if (variable is PrologCodeVariable) { PrologVariableDictionaryEntry entry = _dictionary.GetVariable(((PrologCodeVariable)variable).Name); if (entry != null) { if (entry.IsTemporary && entry.TemporaryIndex == -1) { if (!registers.InUse(xreg)) { _dictionary.AllocateTemporaryVariable(entry, xreg); } } } } xreg++; } } } /* Reserve required registers */ for (int i = 0; i < Math.Max(reg, xreg); i++) { registers.AllocateRegister(i); } /* Emit predicate label */ _generator.DeclareProcedure(clause.Head.Name, clause.Head.Arity); /* Allocate an environment if needed */ if (hasEnvironment) { _generator.Emit(OpCodes.Allocate); } /* Compile clause head */ CompileClauseHead(clause.Head, instructions); /* Set current goal to 1 */ _dictionary.CurrentGoalIndex = 1; if (clause.Goals.Count == 0) { _generator.EndProcedure(); /* Reset variable dictionary */ _dictionary.Reset(); instructions = _generator.Instructions; return; } /* Compile first goal */ CompileGoal(fg, instructions); _dictionary.CurrentGoalIndex++; /* Compile the rest of the goals */ for (int goalIndex = 1; goalIndex < clause.Goals.Count; goalIndex++) { PrologCodeTerm goal = (PrologCodeTerm)clause.Goals[goalIndex]; InitializeGoalTemporaryVariables(goal); /* reserve registers */ for (int i = 0; i < reg; i++) { registers.AllocateRegister(i); } /* Clear temporary index of permanent variables */ _dictionary.ClearTempIndexOfPermanentVariables(); /* Compile goal */ CompileGoal(goal, instructions); /* Advance to next goal */ _dictionary.CurrentGoalIndex += 1; } /* Reset instruction set, code pointer, and variable * dictionary. */ _dictionary.Reset(); }
private void CompileStructArguments(ArrayList arguments) { ArrayList records = new ArrayList(); // TODO: Why is it 20 here? was there a maximum number of records originally. for (int i = 0; i < 20; i++) { records.Add(new Record()); } int nRecs = 0; for (int i = 0; i < arguments.Count; i++) { PrologCodeTerm term = (PrologCodeTerm)arguments[i]; if (term is PrologCodeNilAtom) { _generator.Emit(OpCodes.Unify_Constant, "[]"); } else if (term is PrologCodeAtom) { if (term is PrologCodeConstantAtom) { _generator.Emit(OpCodes.Unify_Constant, ((PrologCodeConstantAtom)term).Value); } else if (term is PrologCodeIntegerAtom) { _generator.Emit(OpCodes.Unify_Constant, ((PrologCodeIntegerAtom)term).Value.ToString()); } else if (term is PrologCodeFloatAtom) { _generator.Emit(OpCodes.Unify_Constant, ((PrologCodeFloatAtom)term).Value.ToString()); } else if (term is PrologCodeStringAtom) { _generator.Emit(OpCodes.Unify_Constant, ((PrologCodeStringAtom)term).Value); } } else if (term is PrologCodeVariable) { PrologVariableDictionaryEntry entry = _dictionary.GetVariable(((PrologCodeVariable)term).Name); if (entry.IsReferenced) { if (entry.IsTemporary) { if (entry.IsGlobal) { _generator.Emit(OpCodes.Unify_Value, X(entry.TemporaryIndex)); } else { // TODO: maybe this should be unify_variable _generator.Emit(OpCodes.Unify_Local_Value, X(entry.TemporaryIndex)); entry.IsGlobal = true; } } else { if (entry.IsGlobal) { _generator.Emit(OpCodes.Unify_Value, Y(entry.PermanentIndex)); } else { _generator.Emit(OpCodes.Unify_Local_Value, Y(entry.PermanentIndex)); } } } // not referenced else { if (entry.IsTemporary) { if (entry.Occurrences == 1) { _generator.Emit(OpCodes.Unify_Void, "1"); } else { // used to be i < entry.TemporaryIndex if (_currArgN < entry.TemporaryIndex && entry.TemporaryIndex < headArity) { entry.TemporaryIndex = PrologRegisterTable.Instance.FindRegister(); } _generator.Emit(OpCodes.Unify_Variable, X(entry.TemporaryIndex)); } } else { _generator.Emit(OpCodes.Unify_Variable, Y(entry.PermanentIndex)); } entry.IsGlobal = true; } } else if (term is PrologCodeEmptyList) { _generator.Emit(OpCodes.Unify_Constant, "[]"); } else { ((Record)records[nRecs]).Term = term; ((Record)records[nRecs]).TemporaryIndex = PrologRegisterTable.Instance.FindRegister(); _generator.Emit(OpCodes.Unify_Variable, X(((Record)records[nRecs]).TemporaryIndex)); nRecs++; } } for (int i = 0; i < nRecs; i++) { Record r = (Record)records[i]; if (r.Term is PrologCodeNonEmptyList) { _generator.Emit(OpCodes.Get_List, X(r.TemporaryIndex)); PrologRegisterTable.Instance.FreeRegister(r.TemporaryIndex); ArrayList listArguments = new ArrayList(); PrologCodeNonEmptyList NEList = (PrologCodeNonEmptyList)r.Term; listArguments.Add(NEList.Head); listArguments.Add(NEList.Tail); CompileStructArguments(listArguments); } else if (r.Term is PrologCodePredicate) { PrologCodePredicate structure = (PrologCodePredicate)r.Term; _generator.Emit(OpCodes.Get_Structure, structure.Name + "/" + structure.Arity, X(r.TemporaryIndex)); CompileStructArguments(structure.Arguments); } else { throw new PrologCompilerException("Unknown argument type (" + r.Term.GetType().ToString() + ") in structure arguments"); } } }
private PrologCodeTerm ConvertGoalVariableBinaryTreeToCodeDOM(BinaryTree var) { if (Char.IsUpper(var.Name[0]) || var.Name[0] == '_' || var.Name == "_") { if (var.Name == "_") { _randomVariableID++; return(new PrologCodeVariable(var.Name + "%" + _randomVariableID.ToString())); } return(new PrologCodeVariable(var.Name)); } else { // Not a functor, => atom | number | string if (var.Arguments == null || var.Arguments.Count == 0) { if (var.Name == ".") { // TODO: can place return PrologCodeEmptyList() here. return(ConvertBinaryListToCodeDOM(var)); } if (var.Left == null && var.Right == null) { // 'Atom string' if (var.Name[0] == '\'') { return(new PrologCodeStringAtom(var.Name)); } else if (Char.IsDigit(var.Name[0])) { // 1.234 if (var.Name.IndexOf('.') != -1) { return(new PrologCodeFloatAtom(float.Parse(var.Name))); } // 213 else { return(new PrologCodeIntegerAtom(Int32.Parse(var.Name))); } } else if (var.Name == "_") { return(new PrologCodeNilAtom()); } // atom else { return(new PrologCodeConstantAtom(var.Name)); } } else if (var.Left != null && var.Right != null) { PrologCodePredicate infixPredicate = new PrologCodePredicate(var.Name); infixPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(var.Left)); infixPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(var.Right)); return(infixPredicate); } else if (var.Left == null && var.Right != null) { PrologCodePredicate prefixPredicate = new PrologCodePredicate(var.Name); prefixPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(var.Right)); return(prefixPredicate); } else if (var.Left != null && var.Right == null) { PrologCodePredicate postfixPredicate = new PrologCodePredicate(var.Name); postfixPredicate.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(var.Left)); return(postfixPredicate); } } // atom(a,X,atom(X)). else { PrologCodePredicate functor = new PrologCodePredicate(var.Name); ArrayList arguments = new ArrayList(); var.Flatten((BinaryTree)var.Arguments[0], ref arguments); foreach (BinaryTree a in arguments) { functor.Arguments.Add(ConvertGoalVariableBinaryTreeToCodeDOM(a)); } return(functor); } } return(null); }