Skip to content

Commit

Permalink
feat: ZScript arrays now are separately typed from non-arrays.
Browse files Browse the repository at this point in the history
Array types can be declared by adding `[]`.
  • Loading branch information
EmilyV99 committed May 3, 2024
1 parent c5da0a5 commit cf2769f
Show file tree
Hide file tree
Showing 17 changed files with 262 additions and 209 deletions.
22 changes: 11 additions & 11 deletions resources/include/bindings/global.zh
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ internal void ClearTile(int tile);
// @zasm
// POP D2
// ARRAYSIZE D2
internal int SizeOfArray(T_ARR arr);
internal int SizeOfArray(T[] arr);

// Resizes the array 'arr' to size 'size'. If 'size' is <1, the array becomes
// size 1 instead.
Expand All @@ -297,21 +297,21 @@ internal int SizeOfArray(T_ARR arr);
// POP D3
// POP D2
// RESIZEARRAYR D2 D3
internal void ResizeArray(T_ARR arr, int size);
internal void ResizeArray(T[] arr, int size);

// Grants ownership of the target array to the currently running script.
//
// @zasm
// POP D2
// OWNARRAYR D2
internal void OwnArray(T_ARR arr);
internal void OwnArray(T[] arr);

// If [arr] is a local array, destroys it immediately. Otherwise does nothing.
//
// @zasm
// POP D2
// DESTROYARRAYR D2
internal void DestroyArray(T_ARR arr);
internal void DestroyArray(T[] arr);

// Takes an Object parameter. Grants ownership of the object to the currently
// running script.
Expand Down Expand Up @@ -483,7 +483,7 @@ internal void itoacat(int dest, int val);
// POP D3
// POP D2
// ARRAYCOPY D2 D3
internal void ArrayCopy(T_ARR dest, T_ARR src);
internal void ArrayCopy(T[] dest, T[] src);

// Returns the length of the string in characters.
//
Expand Down Expand Up @@ -749,7 +749,7 @@ internal T Choose(T arg1);
// PUSHV -1
// ARRAYPUSH
// POPARGS D5 0.0003
internal bool ArrayPushBack(T_ARR arr, T val);
internal bool ArrayPushBack(T[] arr, T val);

// Increases the size of the array by 1, inserting [val] at the
// back/front/specified index of the array. If an invalid index is passed, the
Expand All @@ -759,7 +759,7 @@ internal bool ArrayPushBack(T_ARR arr, T val);
// PUSHV 0
// ARRAYPUSH
// POPARGS D5 0.0003
internal bool ArrayPushFront(T_ARR arr, T val);
internal bool ArrayPushFront(T[] arr, T val);

// Increases the size of the array by 1, inserting [val] at the
// back/front/specified index of the array. If an invalid index is passed, the
Expand All @@ -768,7 +768,7 @@ internal bool ArrayPushFront(T_ARR arr, T val);
// @zasm
// ARRAYPUSH
// POPARGS D5 0.0003
internal bool ArrayPushAt(T_ARR arr, T val, int indx);
internal bool ArrayPushAt(T[] arr, T val, int indx);

// Decreases the size of the array by 1, removing and returning the element at
// the back/front/specified index of the array. If an invalid index is passed,
Expand All @@ -778,7 +778,7 @@ internal bool ArrayPushAt(T_ARR arr, T val, int indx);
// PUSHV -1
// ARRAYPOP
// POPARGS D5 0.0002
internal T ArrayPopBack(T_ARR arr);
internal T ArrayPopBack(T[] arr);

// Decreases the size of the array by 1, removing and returning the element at
// the back/front/specified index of the array. If an invalid index is passed,
Expand All @@ -788,7 +788,7 @@ internal T ArrayPopBack(T_ARR arr);
// PUSHV 0
// ARRAYPOP
// POPARGS D5 0.0002
internal T ArrayPopFront(T_ARR arr);
internal T ArrayPopFront(T[] arr);

// Decreases the size of the array by 1, removing and returning the element at
// the back/front/specified index of the array. If an invalid index is passed,
Expand All @@ -797,7 +797,7 @@ internal T ArrayPopFront(T_ARR arr);
// @zasm
// ARRAYPOP
// POPARGS D5 0.0002
internal T ArrayPopAt(T_ARR arr, int indx);
internal T ArrayPopAt(T[] arr, int indx);

// @zasm
// POP D3
Expand Down
27 changes: 20 additions & 7 deletions src/parser/AST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1763,6 +1763,10 @@ bool ASTExprArrow::isTypeArrowUsrClass() const
{
return u_datum && !u_datum->is_internal;
}
bool ASTExprArrow::isTypeArrowNonUsrClass() const
{
return !isTypeArrowUsrClass();
}

DataType const* ASTExprArrow::getReadType(Scope* scope, CompileErrorHandler* errorHandler)
{
Expand Down Expand Up @@ -1799,7 +1803,7 @@ bool ASTExprIndex::isConstant() const
DataType const* ASTExprIndex::getReadType(Scope* scope, CompileErrorHandler* errorHandler)
{
DataType const* type = array->getReadType(scope, errorHandler);
if (type && type->isArray() && !array->isTypeArrow())
if (type && type->isArray() && !array->isTypeArrowNonUsrClass())
{
DataTypeArray const* atype = static_cast<DataTypeArray const*>(type);
type = &atype->getElementType();
Expand All @@ -1810,7 +1814,7 @@ DataType const* ASTExprIndex::getReadType(Scope* scope, CompileErrorHandler* err
DataType const* ASTExprIndex::getWriteType(Scope* scope, CompileErrorHandler* errorHandler)
{
DataType const* type = array->getWriteType(scope, errorHandler);
if (type && type->isArray() && !array->isTypeArrow())
if (type && type->isArray() && !array->isTypeArrowNonUsrClass())
{
DataTypeArray const* atype = static_cast<DataTypeArray const*>(type);
type = &atype->getElementType();
Expand Down Expand Up @@ -2896,12 +2900,12 @@ ParserScriptType ZScript::resolveScriptType(ASTScriptType const& node,
// ASTDataType

ASTDataType::ASTDataType(DataType* type, LocationData const& location)
: AST(location), type(type->clone()), constant_(0), becomeArray(false),
: AST(location), type(type->clone()), constant_(0), becomeArray(0),
wasResolved_(false)
{}

ASTDataType::ASTDataType(DataType const& type, LocationData const& location)
: AST(location), type(type.clone()), constant_(0), becomeArray(false),
: AST(location), type(type.clone()), constant_(0), becomeArray(0),
wasResolved_(false)
{}

Expand Down Expand Up @@ -2931,10 +2935,19 @@ DataType const& ASTDataType::resolve(ZScript::Scope& scope, CompileErrorHandler*
if(becomeArray)
{
auto* basety = resolved->baseType(scope, errorHandler);
result = new DataTypeArray(*basety);
if(basety)
{
result = new DataTypeArray(*basety);
for(uint q = 1; result && q < becomeArray; ++q)
{
extra_types.push_back(result); //don't leak the memory
result = new DataTypeArray(*result);
}
}
}
else result = resolved->clone();
type.reset(result);
if(result)
type.reset(result);
wasResolved_ = result && result->isResolved();
}
}
Expand All @@ -2949,7 +2962,7 @@ void ASTDataType::replace(DataType const& newty)
{
wasResolved_ = false;
constant_ = false;
becomeArray = false;
becomeArray = 0;
type.reset(newty.clone());
}

5 changes: 4 additions & 1 deletion src/parser/AST.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ namespace ZScript
// Subclass Predicates (replacing typeof and such).
virtual bool isTypeArrow() const {return false;}
virtual bool isTypeArrowUsrClass() const {return false;}
virtual bool isTypeArrowNonUsrClass() const {return false;}
virtual bool isTypeIndex() const {return false;}
virtual bool isTypeIdentifier() const {return false;}
virtual bool isTypeVarDecl() const {return false;}
Expand Down Expand Up @@ -1392,6 +1393,7 @@ namespace ZScript
std::string asString() const;
bool isTypeArrow() const {return true;}
bool isTypeArrowUsrClass() const;
bool isTypeArrowNonUsrClass() const;

bool isConstant() const {return false;}
bool isLiteral() const {return false;}
Expand Down Expand Up @@ -2295,9 +2297,10 @@ namespace ZScript

owning_ptr<DataType> type;
int32_t constant_;
bool becomeArray;
uint becomeArray;
private:
bool wasResolved_;
owning_vector<DataType> extra_types; //nested arrays would leak pointers if not for this
};
}

Expand Down
12 changes: 4 additions & 8 deletions src/parser/BuildVisitors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,11 +344,7 @@ void BuildOpcodes::caseBlock(ASTBlock &host, void *param)
vector<shared_ptr<Opcode>> ops_stack_refs;
for (auto&& datum : scope->getLocalData())
{
// Currently, arrays are not reference counted.
if (datum->type.isArray())
continue;

if (!datum->type.canHoldObject())
if (!datum->type.isObject())
continue;

auto position = lookupStackPosition(*scope, *datum);
Expand Down Expand Up @@ -1614,7 +1610,7 @@ void BuildOpcodes::caseDataDecl(ASTDataDecl& host, void* param)
if (manager.getCompileTimeValue()) return;

// Switch off to the proper helper function.
if (manager.type.isArray()
if (!host.extraArrays.empty()
|| (init && (init->isArrayLiteral()
|| init->isStringLiteral())))
{
Expand All @@ -1640,7 +1636,7 @@ void BuildOpcodes::buildVariable(ASTDataDecl& host, OpcodeContext& context)
visit(init, &context);

auto writeType = &host.resolveType(scope, this);
bool is_object = writeType && writeType->canHoldObject() && !writeType->isArray();
bool is_object = writeType && writeType->isObject();

// Set variable to EXP1 or val, depending on the initializer.
if (auto globalId = manager.getGlobalId())
Expand Down Expand Up @@ -4243,7 +4239,7 @@ void LValBOHelper::caseExprIdentifier(ASTExprIdentifier& host, void* param)

bool is_object = false;
if (auto type = host.getWriteType(scope, nullptr))
is_object = type->canHoldObject() && !type->isArray();
is_object = type->isObject();

if (auto globalId = host.binding->getGlobalId())
{
Expand Down
3 changes: 2 additions & 1 deletion src/parser/CompileError.xtable
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ X( MissingReturnWarn, S, A, W, STR, VOID, "Function '%s' is not void, and shou
X( MissingReturnError, S, A, E, STR, VOID, "Function '%s' is not void, and must return a value!" )
X( NegSqrt, T, A, E, VOID, VOID, "Attempting to take the square root of a negative number!" )
X( ReadOnly, C, A, W, STR, VOID, "'%s' is read-only, and cannot be written to!" )
X( BadInternal, S, A, E, STR, VOID, "%s" )
X( BadInternal, S, A, E, STR, VOID, "%s" )
X( BadVArgType, S, A, E, STR, VOID, "Function varg parameter must have an array type ('%s' is not an array type)" )

#undef STR
18 changes: 8 additions & 10 deletions src/parser/RegistrationVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
extern FFScript FFCore;
using std::ostringstream;
using namespace ZScript;
using std::shared_ptr;
using std::unique_ptr;

int32_t StringToVar(std::string var);
Expand Down Expand Up @@ -729,14 +730,6 @@ void RegistrationVisitor::caseDataDecl(ASTDataDecl& host, void* param)
return;
}

// Currently disabled syntaxes:
if (getArrayDepth(*type) > 1)
{
handleError(CompileError::UnimplementedFeature(
&host, "Nested Array Declarations"));
return;
}

// Is it a constant?
bool isConstant = false;
if (type->isConstant() && !host.list->internal)
Expand Down Expand Up @@ -902,7 +895,7 @@ void RegistrationVisitor::caseFuncDecl(ASTFuncDecl& host, void* param)
// Gather the parameter types.
vector<DataType const*> paramTypes;
vector<ASTDataDecl*> const& params = host.parameters.data();
vector<string const*> paramNames;
vector<shared_ptr<const string>> paramNames;
for (vector<ASTDataDecl*>::const_iterator it = params.begin();
it != params.end(); ++it)
{
Expand All @@ -921,9 +914,14 @@ void RegistrationVisitor::caseFuncDecl(ASTFuncDecl& host, void* param)
scope = oldScope;
return;
}
paramNames.push_back(new string(decl.getName()));
paramNames.emplace_back(new string(decl.getName()));
paramTypes.push_back(type);
}
if(host.getFlag(FUNCFLAG_VARARGS) && !paramTypes.back()->isArray())
{
handleError(CompileError::BadVArgType(&host, paramTypes.back()->getName()));
return;
}
if(host.prototype)
{
//Check the default return
Expand Down
2 changes: 1 addition & 1 deletion src/parser/ReturnVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ void ReturnVisitor::caseDefault(AST& host, void* param)
void ReturnVisitor::analyzeFunctionInternals(Function& function)
{
ASTFuncDecl* node = function.node;
if (!node || node->isDisabled()) return;
ASTBlock* block = node->block.get();
if(!node || node->isDisabled()) return;
if(!block) return;
auto func_var_map = var_map[&function];
if(mode == MODE_FINISH)
Expand Down

0 comments on commit cf2769f

Please sign in to comment.