Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions ctowasm/src/parser/c-ast/expression/unaryExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
* Definition for unary expression nodes.
*/

import { PostfixOperator, PrefixOperator } from "~src/common/types";
import { PostfixOperator, PrefixOperator, ScalarCDataType } from "~src/common/types";
import { CNodeBase, Expression } from "~src/parser/c-ast/core";
import { DataType } from "~src/parser/c-ast/dataTypes";
import { DataType, PrimaryDataType } from "~src/parser/c-ast/dataTypes";

type UnaryExpression =
| PostfixExpression
Expand All @@ -13,7 +13,8 @@ type UnaryExpression =
| StructMemberAccess
| PointerDereference
| AddressOfExpression
| SizeOfExpression;
| SizeOfExpression
| TypeCastingExpression;

export default UnaryExpression;
// All unary expressions should inherit this (like function calls)
Expand All @@ -27,6 +28,12 @@ export interface PostfixExpression extends UnaryExpressionBase {
operator: PostfixOperator;
}

export interface TypeCastingExpression extends UnaryExpressionBase {
type: "TypeCastingExpression";
expr: Expression;
targetDataType: PrimaryDataType;
}

export interface PrefixExpression extends UnaryExpressionBase {
type: "PrefixExpression";
operator: PrefixOperator;
Expand Down
18 changes: 17 additions & 1 deletion ctowasm/src/parser/peggyjs/parser.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@
/**
* Helper function to create and return a Node with position and type information
*/
function createTypeCastNode(type, expr) {
// Perform type checking for the cast
if (type.primaryDataType === "void") {
error("Cannot cast to void type");
}
if (expr.type === "StructMemberAccess" || expr.type === "StructPointerMemberAccess") {
error("Cannot cast struct or struct pointer types");
}

return generateNode("TypeCastingExpression", {
expr: expr,
targetDataType: type,
});
}

function generateNode(type, data) {
return {
type: type,
Expand Down Expand Up @@ -1938,7 +1953,8 @@ multiply_divide_expression
/ unary_expression // as the last binary expression (highest precedence), this rule is needed

unary_expression
= operations:(@prefix_operation _)+ firstExpr:postfix_expression { return createPrefixExpressionNode(firstExpr, operations); }
= "(" _ type:type_name _ ")" _ expr:unary_expression { return createTypeCastNode(type, expr); }
/ operations:(@prefix_operation _)+ firstExpr:postfix_expression { return createPrefixExpressionNode(firstExpr, operations); }
/ postfix_expression

prefix_operation
Expand Down
18 changes: 18 additions & 0 deletions ctowasm/src/processor/processExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,24 @@ export default function processExpression(
...returnObjectMemoryLoads.slice(1),
],
};
} else if (expr.type === "TypeCastingExpression") {
// type casting is just a way to tell the compiler to treat an expression as another type
// no actual conversion is done here
const processedExpr = processExpression(expr.expr, symbolTable);
const targetDataType = expr.targetDataType;

return {
originalDataType: targetDataType,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the originalDataType type here does not seem to be used anywhere. How does the type conversion (e.g. int-> float) actually work in that case?

exprs: [
{
type: "PreStatementExpression",
statements: [],
expr: processedExpr.exprs[0],
dataType: processedExpr.exprs[0].dataType,
},
...processedExpr.exprs.slice(1),
],
};
} else if (expr.type === "PrefixExpression") {
return processPrefixExpression(expr, symbolTable);
} else if (expr.type === "PostfixExpression") {
Expand Down
8 changes: 8 additions & 0 deletions ctowasm/src/translator/translateExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ export default function translateExpression(
) {
return convertConstantToWasmConst(expr);
} else if (expr.type === "PreStatementExpression") {
const translatedStatements = expr.statements.map((statement) =>
translateStatement(statement, enclosingLoopDetails),
);
const translatedExpr = translateExpression(
expr.expr,
expr.expr.dataType,
enclosingLoopDetails,
);
Comment on lines +45 to +52
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These variables do not seem to be used anywhere. What is their purpose?

return {
type: "PreStatementExpression",
statements: expr.statements.map((statement) =>
Expand Down