/* 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++; } } } } }
public void Add(object key, object val) { string name = (string)key; if (this.Contains(key)) { PrologVariableDictionaryEntry entry = GetEntry((string)key); entry.Occurrences += 1; entry.LastGoal = _currentGoalIndex; entry.LastGoalArgument = _currentArgumentIndex; } else { PrologVariableDictionaryEntry variable = new PrologVariableDictionaryEntry(name, -1); variable.Occurrences = 0; variable.FirstGoal = _currentGoalIndex; variable.IsReferenced = false; variable.IsGlobal = false; variable.Occurrences += 1; variable.LastGoal = _currentGoalIndex; variable.LastGoalArgument = _currentArgumentIndex; variable.IsReferenced = false; _items.Add(variable); } }
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); }
public void Remove(object key) { if (key == null) { throw new ArgumentNullException("key"); } string name = (string)key; for (int i = 0; i < _items.Count; i++) { PrologVariableDictionaryEntry entry = (PrologVariableDictionaryEntry)_items[i]; if (entry.Name == name) { _items.RemoveAt(i); return; } } }
public void AllocatePermanentVariable(PrologVariableDictionaryEntry entry, int reg) { entry.PermanentIndex = reg; }
public void AllocateTemporaryVariable(PrologVariableDictionaryEntry entry, int reg) { _registers.AllocateRegister(reg); entry.TemporaryIndex = reg; }
private void CompileGoalRecordVariable(PrologCodeVariable var) { PrologVariableDictionaryEntry entry = _dictionary.GetVariable(var.Name); if (entry.IsReferenced) { /* Compile build value here ... */ if (entry.IsTemporary) { if (entry.IsGlobal) { _generator.Emit(OpCodes.Set_Value, X(entry.TemporaryIndex)); } else { _generator.Emit(OpCodes.Set_Local_Value, X(entry.TemporaryIndex)); entry.IsGlobal = true; } } else { if (entry.IsGlobal) { if (entry.TemporaryIndex != -1) { _generator.Emit(OpCodes.Set_Value, X(entry.TemporaryIndex)); } else { _generator.Emit(OpCodes.Set_Value, Y(entry.PermanentIndex)); } } else { if (entry.TemporaryIndex != -1) { _generator.Emit(OpCodes.Set_Local_Value, X(entry.TemporaryIndex)); } else { _generator.Emit(OpCodes.Set_Local_Value, Y(entry.PermanentIndex)); } } } } else { if (entry.IsTemporary) { if (entry.Occurrences == 1) { _generator.Emit(OpCodes.Set_Void, "1"); } else { _generator.Emit(OpCodes.Set_Variable, X(entry.TemporaryIndex)); } } else { _generator.Emit(OpCodes.Set_Variable, Y(entry.PermanentIndex)); } entry.IsGlobal = true; } }
private void CompileGoalVariable(PrologCodeVariable var, int i) { PrologVariableDictionaryEntry entry = _dictionary.GetVariable(var.Name); if (entry.IsTemporary) { if (entry.TemporaryIndex != i) { ResolveConflicts(var, i); } if (entry.IsReferenced) { if (entry.TemporaryIndex != i) { _generator.Emit(OpCodes.Put_Value, X(entry.TemporaryIndex), X(i)); } } else { if (entry.TemporaryIndex != i) { _generator.Emit(OpCodes.Put_Variable, X(entry.TemporaryIndex), X(i)); } else { _generator.Emit(OpCodes.Put_Variable, X(i), X(i)); } entry.IsGlobal = true; } } else { ResolveConflicts(var, i); if (entry.IsReferenced) { if (entry.IsUnsafe && !entry.IsGlobal && _dictionary.InLastGoal) { _generator.Emit(OpCodes.Put_Unsafe_Value, Y(entry.PermanentIndex), X(i)); entry.IsUnsafe = false; } else { if (entry.TemporaryIndex != -1) { _generator.Emit(OpCodes.Put_Value, X(entry.TemporaryIndex), X(i)); } else { _generator.Emit(OpCodes.Put_Value, Y(entry.PermanentIndex), X(i)); } } } else { _generator.Emit(OpCodes.Put_Variable, Y(entry.PermanentIndex), X(i)); } if (entry.TemporaryIndex == -1) { entry.TemporaryIndex = i; } else { // No } } }
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 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 Add(object key, object val) { string name = (string)key; if(this.Contains(key)) { PrologVariableDictionaryEntry entry = GetEntry((string)key); entry.Occurrences += 1; entry.LastGoal = _currentGoalIndex; entry.LastGoalArgument = _currentArgumentIndex; } else { PrologVariableDictionaryEntry variable = new PrologVariableDictionaryEntry(name, -1); variable.Occurrences = 0; variable.FirstGoal = _currentGoalIndex; variable.IsReferenced = false; variable.IsGlobal = false; variable.Occurrences += 1; variable.LastGoal = _currentGoalIndex; variable.LastGoalArgument = _currentArgumentIndex; variable.IsReferenced = false; _items.Add(variable); } }