Skip to content

Commit

Permalink
Pulled from Google's internal repo.
Browse files Browse the repository at this point in the history
  • Loading branch information
waywardgeek committed Jan 27, 2023
1 parent 6d33d15 commit ecdb1ac
Show file tree
Hide file tree
Showing 30 changed files with 197 additions and 25 deletions.
3 changes: 3 additions & 0 deletions database/datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,9 @@ static char *getEnumClassTypeString(deDatatype datatype) {
// Return a Rune formatted type string corresponding to this datatype. The
// datatype must be instantiatable, meaning Class, not Tclass.
char *deDatatypeGetTypeString(deDatatype datatype) {
if (datatype == deDatatypeNull) {
return "<null datatype>";
}
if (deDatatypeSecret(datatype)) {
return utSprintf("secret(%s)", deDatatypeGetTypeString(deSetDatatypeSecret(datatype, false)));
}
Expand Down
3 changes: 3 additions & 0 deletions database/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,9 @@ deExpression deCopyExpression(deExpression expression) {
case DE_EXPR_INTTYPE:
deExpressionSetWidth(newExpression, deExpressionGetWidth(expression));
break;
case DE_EXPR_FLOAT:
deExpressionSetFloat(newExpression, deExpressionGetFloat(expression));
break;
default:
break;
}
Expand Down
38 changes: 25 additions & 13 deletions database/function.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,29 @@ deFunction deFunctionCreate(deFilepath filepath, deBlock block, deFunctionType t
return function;
}

// Make a copy of the function in |destBlock|.
deFunction deCopyFunction(deFunction function, deBlock destBlock) {
// Make a copy of the function in |destBlock|, either with or without sub-blocks.
static deFunction copyFunction(deFunction function, deBlock destBlock, bool shallow) {
deBlock subBlock = deFunctionGetSubBlock(function);
deFunctionType type = deFunctionGetType(function);
deFunction newFunction = deFunctionCreate(deBlockGetFilepath(subBlock), destBlock, type,
deFunctionGetSym(function), deFunctionGetLinkage(function), deFunctionGetLine(function));
deBlock newBlock = deCopyBlock(subBlock);
deBlock newBlock;
if (shallow) {
newBlock = deShallowCopyBlock(subBlock);
} else {
newBlock = deCopyBlock(subBlock);
}
deFunctionInsertSubBlock(newFunction, newBlock);
if (type == DE_FUNC_CONSTRUCTOR) {
deCopyTclass(deFunctionGetTclass(function), newFunction);
deExpression typeConstraint = deFunctionGetTypeExpression(function);
if (typeConstraint != deExpressionNull) {
deExpression newTypeConstraint = deCopyExpression(typeConstraint);
deFunctionInsertTypeExpression(newFunction, newTypeConstraint);
}
if (!shallow) {
deFunctionType type = deFunctionGetType(function);
if (type == DE_FUNC_CONSTRUCTOR) {
deCopyTclass(deFunctionGetTclass(function), newFunction);
}
}
deRelation relation = deFunctionGetGeneratedRelation(function);
if (relation != deRelationNull) {
Expand All @@ -120,15 +133,14 @@ deFunction deCopyFunction(deFunction function, deBlock destBlock) {
return newFunction;
}

// Make a copy of the function in |destBlock|, without sub-blocks.
// Make a copy of the function in |destBlock|.
deFunction deCopyFunction(deFunction function, deBlock destBlock) {
return copyFunction(function, destBlock, false);
}

// Make a shallow copy of the function in |destBlock|.
deFunction deShallowCopyFunction(deFunction function, deBlock destBlock) {
deBlock subBlock = deFunctionGetSubBlock(function);
deFunctionType type = deFunctionGetType(function);
deFunction newFunction = deFunctionCreate(deBlockGetFilepath(subBlock), destBlock, type,
deFunctionGetSym(function), deFunctionGetLinkage(function), deFunctionGetLine(function));
deBlock newBlock = deShallowCopyBlock(subBlock);
deFunctionInsertSubBlock(newFunction, newBlock);
return newFunction;
return copyFunction(function, destBlock, true);
}

// Append a call statement to the module initialization function in the root block.
Expand Down
5 changes: 5 additions & 0 deletions database/variable.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ deVariable deCopyVariable(deVariable variable, deBlock destBlock) {
}
deVariable newVariable = deVariableCreate(destBlock, deVariableGetType(variable), deVariableConst(variable),
deVariableGetSym(variable), initializer, deVariableGenerated(variable), deVariableGetLine(variable));
deExpression typeConstraint = deVariableGetTypeExpression(variable);
if (typeConstraint != deExpressionNull) {
deExpression newTypeConstraint = deCopyExpression(typeConstraint);
deVariableInsertTypeExpression(variable, newTypeConstraint);
}
return newVariable;
}

Expand Down
1 change: 1 addition & 0 deletions include/de.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void deInlineIterators(void);
void deBindAllSignatures(void);
void deBindStatement2(deBinding binding);
void deQueueSignature(deSignature signature);
void deQueueBlockStatements(deSignature signature, deBlock block, bool instantiating);
void deQueueStatement(deSignature signature, deStatement statement,
bool instantiating);
void deQueueExpression(deBinding binding, deExpression expression,
Expand Down
14 changes: 13 additions & 1 deletion llvm/llvmdecls.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,18 @@ char *llStringGetName(deString string) {
return utSprintf("@.str%u", llStringGetNum(string));
}

// For default params, we get the datatype from the default initializer expression.
static deDatatype getParamspecGetDatatype(deParamspec paramspec) {
deDatatype datatype = deParamspecGetDatatype(paramspec);
if (datatype != deDatatypeNull) {
return datatype;
}
utAssert(deUseNewBinder);
deBlock block = deSignatureGetUniquifiedBlock(deParamspecGetSignature(paramspec));
deVariable param = deBlockIndexVariable(block, deParamspecGetSignatureIndex(paramspec));
return deVariableGetDatatype(param);
}

// Declare an extern "C" function.
static void declareExternCFunction(deSignature signature) {
deFunction function = deSignatureGetFunction(signature);
Expand All @@ -676,7 +688,7 @@ static void declareExternCFunction(deSignature signature) {
llPuts(", ");
}
first = false;
deDatatype datatype = deParamspecGetDatatype(paramspec);
deDatatype datatype = getParamspecGetDatatype(paramspec);
llPrintf("%s", llGetTypeString(datatype, false));
} deEndSignatureParamspec;
llPuts(")\n");
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
14 changes: 14 additions & 0 deletions newtests/mylistitr.rn
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// Copyright 2021 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

appendcode Array {
iterator myValues(self) {
for i = 0, i < self.length(), i += 1 {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
93 changes: 85 additions & 8 deletions src/bind2.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ void deQueueExpression(deBinding binding, deExpression expression, bool instanti
}

// Forward reference for recursion.
static void queueBlockStatements(deSignature signature, deBlock block, bool instantiating);
void deQueueBlockStatements(deSignature signature, deBlock block, bool instantiating);

// Queue the statement and its sub-block's statements.
void deQueueStatement(deSignature signature, deStatement statement, bool instantiating) {
Expand All @@ -249,13 +249,15 @@ void deQueueStatement(deSignature signature, deStatement statement, bool instant
}
}
deBlock subBlock = deStatementGetSubBlock(statement);
if (subBlock != deBlockNull) {
queueBlockStatements(signature, subBlock, instantiating);
if (subBlock != deBlockNull && deStatementGetType(statement) != DE_STATEMENT_TYPESWITCH) {
// We only bind the first typeswitch sub-block that matches. It is queued
// as a post-process to binding the typeswitch statement.
deQueueBlockStatements(signature, subBlock, instantiating);
}
}

// Throw all the expressions in the block into the queue to be bound.
static void queueBlockStatements(deSignature signature, deBlock block, bool instantiating) {
void deQueueBlockStatements(deSignature signature, deBlock block, bool instantiating) {
deStatement statement;
deForeachBlockStatement(block, statement) {
deQueueStatement(signature, statement, instantiating);
Expand All @@ -275,6 +277,32 @@ static void createDefaultValueBinding(deSignature signature, deVariable var) {
deQueueExpression(binding, expr, true);
}

// Create a Binding for a variable's type constraint.
static void createVariableConstraintBinding(deSignature signature, deVariable var) {
deBinding binding = deVariableGetTypeBinding(var);
if (binding != deBindingNull) {
// Rebind the type constraint expression in case we've made changes.
deBindingDestroy(binding);
}
binding = deVariableConstraintBindingCreate(signature, var, true);
deExpression expr = deVariableGetTypeExpression(var);
utAssert(expr != deExpressionNull);
deQueueExpression(binding, expr, true);
}

// Create a Binding for a function's type constraint.
static void createFunctionConstraintBinding(deSignature signature, deFunction func) {
deBinding binding = deFunctionGetTypeBinding(func);
if (binding != deBindingNull) {
// Rebind the type constraint expression in case we've made changes.
deBindingDestroy(binding);
}
binding = deFunctionConstraintBindingCreate(signature, func, true);
deExpression expr = deFunctionGetTypeExpression(func);
utAssert(expr != deExpressionNull);
deQueueExpression(binding, expr, true);
}

// Bind parameter variables from the signature. For parameters with
// deNullDatatype, there must be a default value. Create Binding objects for
// such variables. Also create Binding objects for parameter type constraints.
Expand All @@ -288,6 +316,9 @@ static void bindSignatureParameters(deSignature signature) {
} else {
deVariableSetDatatype(variable, deParamspecGetDatatype(paramspec));
}
if (deVariableGetTypeExpression(variable) != deExpressionNull) {
createVariableConstraintBinding(signature, variable);
}
variable = deVariableGetNextBlockVariable(variable);
} deEndSignatureParamspec;
}
Expand Down Expand Up @@ -326,6 +357,41 @@ static deDatatype findStructDatatype(deSignature signature) {
return deStructDatatypeCreate(function, types, deSignatureGetLine(signature));
}

// Update an external signature. Check that the return type and all variable
// parameters are concrete. Mark all parameters as instantiated.
static void updateExternSignature(deSignature signature) {
deFunction function = deSignatureGetUniquifiedFunction(signature);
deExpression typeExpr = deFunctionGetTypeExpression(function);
if (typeExpr == deExpressionNull) {
deSignatureSetReturnType(signature, deNoneDatatypeCreate());
} else {
deDatatype datatype = deExpressionGetDatatype(typeExpr);
if (datatype == deDatatypeNull || !deDatatypeConcrete(datatype)) {
printf("Extern function return type: %s\n", deDatatypeGetTypeString(datatype));
deError(deSignatureGetLine(signature), "Extern function return types must be concrete");
}
deSignatureSetReturnType(signature, datatype);
}
deBlock block = deSignatureGetUniquifiedBlock(signature);
deVariable var = deBlockGetFirstVariable(block);
deParamspec param;
deForeachSignatureParamspec(signature, param) {
deDatatype datatype = deVariableGetDatatype(var);
utAssert(datatype != deDatatypeNull);
if (!deDatatypeConcrete(datatype)) {
printf("%s type: %s\n", deVariableGetName(var), deDatatypeGetTypeString(datatype));
deError(deSignatureGetLine(signature), "Extern function parameter types must be concrete");
}
deVariableSetInstantiated(var, true);
deParamspecSetInstantiated(param, true);
var = deVariableGetNextBlockVariable(var);
} deEndSignatureParamspec;
if (!deSignatureBound(signature)) {
deSignatureSetBound(signature, true);
deQueueEventBlockedBindings(deSignatureGetReturnEvent(signature));
}
}

// Once we finish expression a signature, update its paramspecs.
static void updateSignature(deSignature signature) {
deBlock block = deSignatureGetUniquifiedBlock(signature);
Expand All @@ -334,18 +400,25 @@ static void updateSignature(deSignature signature) {
deForeachSignatureParamspec(signature, param) {
utAssert(var != deVariableNull && deVariableGetType(var) == DE_VAR_PARAMETER);
deParamspecSetIsType(param, deVariableIsType(var));
if (!deVariableConst(var)) {
// Mark all var parameters as instantiated.
deVariableSetInstantiated(var, true);
}
deParamspecSetInstantiated(param, deVariableInstantiated(var));
var = deVariableGetNextBlockVariable(var);
} deEndSignatureParamspec;
utAssert(var == deVariableNull || deVariableGetType(var) != DE_VAR_PARAMETER);
deFunctionType type = deFunctionGetType(deSignatureGetFunction(signature));
deFunction function = deSignatureGetUniquifiedFunction(signature);
deFunctionType type = deFunctionGetType(function);
if (type == DE_FUNC_DESTRUCTOR) {
// The self variable of destructors needs to be marked as instantiated.
deParamspecSetInstantiated(deSignatureGetiParamspec(signature, 0), true);
} else if (type == DE_FUNC_STRUCT) {
deSignatureSetReturnType(signature, findStructDatatype(signature));
deQueueEventBlockedBindings(deSignatureGetReturnEvent(signature));
deSignatureSetBound(signature, true);
} else if (deFunctionExtern(function)) {
updateExternSignature(signature);
}
}

Expand All @@ -356,13 +429,17 @@ void deQueueSignature(deSignature signature) {
}
deSignatureSetQueued(signature, true);
deBlock block = deSignatureGetUniquifiedBlock(signature);
deFunction func = deSignatureGetFunction(signature);
deFunction func = deSignatureGetUniquifiedFunction(signature);
deFunctionType type = deFunctionGetType(func);
if (!deFunctionBuiltin(func) && type != DE_FUNC_ITERATOR && type != DE_FUNC_STRUCT) {
if (!deFunctionBuiltin(func) && type != DE_FUNC_ITERATOR && type != DE_FUNC_STRUCT &&
!deFunctionExtern(func)) {
addReturnIfMissing(block);
}
bindSignatureParameters(signature);
queueBlockStatements(signature, block, true);
if (deFunctionGetTypeExpression(func) != deExpressionNull) {
createFunctionConstraintBinding(signature, func);
}
deQueueBlockStatements(signature, block, true);
if (deSignatureGetFirstBinding(signature) == deBindingNull) {
// This signature has nothing to bind.
updateSignature(signature);
Expand Down
51 changes: 48 additions & 3 deletions src/bindexpr.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,13 @@ static void bindNullExpression(deBlock scopeBlock, deExpression expression) {
deExpressionSetDatatype(expression, datatype);
}

// Bind a notnull expression.
static void bindNotNullExpression(deBlock scopeBlock, deExpression expression) {
deDatatype datatype = deSetDatatypeNullable(bindUnaryExpression(scopeBlock, expression), false,
deExpressionGetLine(expression));
deExpressionSetDatatype(expression, datatype);
}

// Set all the variables passed as instantiated. Any function that can be
// called through a pointer must accept all parameters on the stack, even if
// they are unused, or only used for their types.
Expand Down Expand Up @@ -1426,7 +1433,7 @@ static deBindRes bindExpression(deBlock scopeBlock, deExpression expression) {
bindNullExpression(scopeBlock, expression);
break;
case DE_EXPR_NOTNULL:
utExit("Write me");
bindNotNullExpression(scopeBlock, expression);
break;
case DE_EXPR_FUNCADDR:
bindFunctionPointerExpression(expression);
Expand Down Expand Up @@ -1506,8 +1513,44 @@ static void updateSignatureReturnType(deSignature signature, deDatatype datatype
}
}

// Select the matching case of a typeswitch statement.
static void selectMatchingCase(deBlock scopeBlock, deBinding binding) {
deStatement typeSwitchStatement = deBindingGetStatement(binding);
deDatatype datatype = deExpressionGetDatatype(deStatementGetExpression(typeSwitchStatement));
bool instantiating = deBindingInstantiated(binding);
utAssert(datatype != deDatatypeNull);
deBlock subBlock = deStatementGetSubBlock(typeSwitchStatement);
bool foundMatchingCase = false;
deStatement caseStatement;
deForeachBlockStatement(subBlock, caseStatement) {
deStatementSetInstantiated(caseStatement, false);
if (!foundMatchingCase) {
if (deStatementGetType(caseStatement) == DE_STATEMENT_CASE) {
deExpression typeExpressionList = deStatementGetExpression(caseStatement);
deExpression typeExpression;
deForeachExpressionExpression(typeExpressionList, typeExpression) {
if (deDatatypeMatchesTypeExpression(scopeBlock, datatype, typeExpression)) {
foundMatchingCase = true;
}
} deEndExpressionExpression;
} else {
utAssert(deStatementGetType(caseStatement) == DE_STATEMENT_DEFAULT);
foundMatchingCase = true;
}
if (foundMatchingCase && instantiating) {
deStatementSetInstantiated(caseStatement, true);
deBlock caseBlock = deStatementGetSubBlock(caseStatement);
deQueueBlockStatements(deBindingGetSignature(binding), caseBlock, instantiating);
}
}
} deEndBlockStatement;
if (!foundMatchingCase) {
deError(deStatementGetLine(typeSwitchStatement), "No matching case found");
}
}

// Depending on the statement type, we may have some tasks to do once the statement is bound.
static void postProcessBoundStatement(deBinding binding) {
static void postProcessBoundStatement(deBlock scopeBlock, deBinding binding) {
deStatement statement = deBindingGetStatement(binding);
deStatementSetInstantiated(statement, deBindingInstantiated(binding));
deStatementType type = deStatementGetType(statement);
Expand All @@ -1517,6 +1560,8 @@ static void postProcessBoundStatement(deBinding binding) {
datatype = deExpressionGetDatatype(deStatementGetExpression(statement));
}
updateSignatureReturnType(deBindingGetSignature(binding), datatype);
} else if (type == DE_STATEMENT_TYPESWITCH) {
selectMatchingCase(scopeBlock, binding);
}
}

Expand Down Expand Up @@ -1557,7 +1602,7 @@ void deBindStatement2(deBinding binding) {
}
switch (deBindingGetType(binding)) {
case DE_BIND_STATEMENT:
postProcessBoundStatement(binding);
postProcessBoundStatement(scopeBlock, binding);
break;
case DE_BIND_DEFAULT_VALUE:
setDefaultVariableType(scopeBlock, binding);
Expand Down

0 comments on commit ecdb1ac

Please sign in to comment.