Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for new intrinsic data types: Strings and arrays.
- Loading branch information
Showing
3 changed files
with
347 additions
and
0 deletions.
There are no files selected for viewing
86 changes: 86 additions & 0 deletions
86
last/toby/interpreter/ArrayDereferenceExpressionLogicContext.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* | ||
* TOBY -- A LOGO-like interpreted language, written in 100% pure Java. | ||
* Copyright (C) 1999 Ryan C. Gordon. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version 2 | ||
* of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
*/ | ||
|
||
package last.toby.interpreter; | ||
import last.toby.util.*; | ||
import last.toby.exceptions.*; | ||
|
||
/** | ||
* !!! comment me! | ||
* @author Ryan C. Gordon. | ||
*/ | ||
|
||
// !!! Dang...that's a long class name. | ||
public class ArrayDereferenceExpressionLogicContext | ||
extends BinaryExpressionLogicContext | ||
{ | ||
// children[0] == array to dereference. | ||
// children[1] == index of element in array. | ||
|
||
private boolean autoCast = false; | ||
|
||
public ArrayDereferenceExpressionLogicContext(int sourceLine, | ||
boolean autoCast) | ||
{ | ||
super(sourceLine); | ||
this.autoCast = autoCast; | ||
} // Constructor | ||
|
||
|
||
/* !!! lose this if the below !!! can't be resolved. | ||
protected void linkImpl(GlobalLogicContext glob) throws ParseException | ||
{ | ||
super.linkImpl(glob); | ||
!!! children[0] will never be an ArrayIntrinsic, since, at best, it | ||
!!! will be an IntrinsicLogicContext wrapper. | ||
if ( ((children[0] instanceof ArrayIntrinsic) == false) && | ||
((children[0] instanceof ArrayDereferenceExpressionLogicContext) == false) ) | ||
{ | ||
ParseException._throw(TobyLanguage.NOT_AN_ARRAY); | ||
} // if | ||
} // linkImpl | ||
*/ | ||
|
||
protected Intrinsic executeImpl(Intrinsic operand1, Intrinsic operand2) | ||
throws FlowException | ||
{ | ||
// the getIntrinsicValue() call will pull the array out of | ||
// a VarReferenceIntrinsic, it is wrapped as such. | ||
ArrayIntrinsic intr = (ArrayIntrinsic) operand1.getIntrinsicValue(); | ||
int index = 0; | ||
|
||
if (this.autoCast == true) | ||
index = operand2.getIntValue(); | ||
else | ||
{ | ||
double d = operand2.getDoubleValue(); | ||
index = (int) d; | ||
if ( (d - ((double) index)) != 0.0 ) | ||
ExecException._throw(TobyLanguage.NOT_WHOLE_NUM); | ||
} // else | ||
|
||
return(intr.getElement(index)); | ||
} // executeImpl | ||
|
||
} // ArrayDereferenceExpressionLogicContext | ||
|
||
// end of ArrayDereferenceExpressionLogicContext.java ... | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
/* | ||
* TOBY -- A LOGO-like interpreted language, written in 100% pure Java. | ||
* Copyright (C) 1999 Ryan C. Gordon. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version 2 | ||
* of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
*/ | ||
|
||
package last.toby.interpreter; | ||
import last.toby.util.*; | ||
import last.toby.exceptions.*; | ||
|
||
/** | ||
* !!! comment me! | ||
* | ||
* @author Ryan C. Gordon. (icculus@lokigames.com) | ||
*/ | ||
public class ArrayIntrinsic extends Intrinsic | ||
{ | ||
protected Intrinsic[] elements = null; | ||
protected int index_offset = -1; | ||
|
||
|
||
// !!! being able to turn off range checking might be a nice, dangerous | ||
// !!! speed hack. | ||
|
||
|
||
/* | ||
* Note that ArrayIntrinsics are constructed without any element storage. | ||
* Before you can store Intrinsics in the array, you need to | ||
* call redim() to define some space. This should probably be | ||
* done as the first instructions in a FunctionLogicContext (or | ||
* GlobalLogicContext, for globally-scoped arrays), in the same | ||
* way that prepended instructions are used to set the initial values | ||
* of simple Intrinsic types like NumberIntrinsic. | ||
*/ | ||
|
||
|
||
/* | ||
* (Re)size the array. | ||
* | ||
* @param start_index index of initial array element. A pascal array | ||
* with a range of [5 .. 10] would specify 5 here. | ||
* @param end_index index of final array element. A pascal array | ||
* with a range of [5 .. 10] would specify 10. | ||
* @param dummy_element Intrinsic to fill array with. The filling | ||
* is done with dummy_element.getCopy(). | ||
* If this is too time/memory draining for you, | ||
* You can specify null, in which case the | ||
* array will have Java null references, which | ||
* will cause a crash unrelated to your | ||
* interpreted language if dereferenced. For | ||
* interpreting something like C, however, | ||
* this might be preferable behaviour on all | ||
* counts. | ||
*/ | ||
public void redim(int start_index, int end_index, Intrinsic dummy_element) | ||
{ | ||
int new_size = end_index - start_index + 1; | ||
this.index_offset = start_index; | ||
Intrinsic[] new_array = new Intrinsic[new_size]; | ||
int empty_space = new_size; | ||
int empty_start_index = 0; | ||
|
||
if (elements == null) | ||
elements = new_array; | ||
else | ||
{ | ||
for (int i = 0; i < elements.length; i++) | ||
{ | ||
if (i < new_size) | ||
new_array[i] = elements[i]; | ||
elements[i] = null; | ||
} // for | ||
|
||
empty_space = new_size - elements.length; | ||
empty_start_index = elements.length; | ||
elements = new_array; | ||
} // else | ||
|
||
if (empty_space > 0) | ||
{ | ||
for (int i = empty_start_index; i < new_size; i++) | ||
{ | ||
if (dummy_element == null) | ||
elements[i] = null; | ||
else | ||
elements[i] = dummy_element.getCopy(); | ||
} // for | ||
} // if | ||
} // redim | ||
|
||
public Intrinsic getElement(int index) throws ExecException | ||
{ | ||
index -= index_offset; | ||
|
||
if ((index < 0) || (index >= elements.length)) | ||
ExecException._throw(TobyLanguage.OUT_OF_RANGE); | ||
|
||
return(elements[index]); | ||
} // getElement | ||
|
||
|
||
// chances are this isn't needed; usually you'll getElement() an | ||
// Intrinsic, and then set values on that directly. This is for | ||
// dropping a new Intrinsic item into an array slot. | ||
public void setElement(int index, Intrinsic new_value) throws ExecException | ||
{ | ||
index -= index_offset; | ||
|
||
if ((index < 0) || (index >= elements.length)) | ||
ExecException._throw(TobyLanguage.OUT_OF_RANGE); | ||
|
||
elements[index] = new_value; | ||
} // setElement | ||
|
||
|
||
public boolean isConstantValue() | ||
{ | ||
return(false); | ||
} // isConstantValue | ||
|
||
|
||
public String toString() | ||
{ | ||
return(name + "array://" + getIdentifier() + ":" + index_offset + "-" + | ||
(elements.length - index_offset) + ")"); | ||
} // toString | ||
|
||
protected Intrinsic getCopyImpl() | ||
{ | ||
ArrayIntrinsic retval = new ArrayIntrinsic(); | ||
|
||
if (elements != null) | ||
{ | ||
retval.elements = new Intrinsic[elements.length]; | ||
for (int i = 0; i < elements.length; i++) | ||
{ | ||
if (elements[i] == null) | ||
retval.elements[i] = null; | ||
else | ||
retval.elements[i] = elements[i].getCopy(); | ||
} // for | ||
} // if | ||
|
||
retval.index_offset = index_offset; | ||
return(retval); | ||
} // getCopyImpl | ||
|
||
protected void linkImpl(GlobalLogicContext glob) throws ParseException | ||
{ | ||
if (elements != null) | ||
{ | ||
for (int i = 0; i < elements.length; i++) | ||
{ | ||
if ((elements[i] != null) && (elements[i] instanceof Linkable)) | ||
((Linkable) elements[i]).link(glob); | ||
} // for | ||
} // if | ||
} // linkImpl | ||
} // ArrayIntrinsic | ||
|
||
// end of ArrayIntrinsic.java ... | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* | ||
* TOBY -- A LOGO-like interpreted language, written in 100% pure Java. | ||
* Copyright (C) 1999 Ryan C. Gordon. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version 2 | ||
* of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
*/ | ||
|
||
package last.toby.interpreter; | ||
import last.toby.exceptions.*; | ||
import last.toby.util.TobyLanguage; | ||
|
||
/** | ||
* !!! write me. | ||
* @author Ryan C. Gordon. (icculus@lokigames.com) | ||
*/ | ||
public class StringIntrinsic extends Intrinsic | ||
{ | ||
protected String data = null; | ||
|
||
public StringIntrinsic(String str) | ||
{ | ||
this.data = str; | ||
} // Constructor | ||
|
||
public StringIntrinsic() | ||
{ | ||
this(""); | ||
} // Constructor | ||
|
||
public void setValue(String newVal) throws FlowException | ||
{ | ||
this.data = newVal; | ||
} // setValue | ||
|
||
public void setValue(Intrinsic newVal) throws FlowException | ||
{ | ||
this.data = newVal.getStringValue(); | ||
} // setValue | ||
|
||
public String getStringValue() throws FlowException | ||
{ | ||
return(this.data); | ||
} // getValue | ||
|
||
public int compare(Intrinsic intr) throws FlowException | ||
{ | ||
String compareStr = intr.getStringValue(); | ||
return(compareStr.compareTo(data)); | ||
} // compare | ||
|
||
public boolean isEqual(Intrinsic intr) throws FlowException | ||
{ | ||
return(this.compare(intr) == 0); | ||
} // isEqual | ||
|
||
public boolean isConstantValue() | ||
{ | ||
return(true); | ||
} // isConstantValue | ||
|
||
protected Intrinsic getCopyImpl() | ||
{ | ||
return(new StringIntrinsic(this.data)); | ||
} // getCopyImpl | ||
|
||
protected void linkImpl(GlobalLogicContext glob) throws ParseException | ||
{ | ||
// no link, here. | ||
} // linkImpl | ||
|
||
} // StringIntrinsic | ||
|
||
// end of StringIntrinsic.java ... | ||
|