.{ -1, 0 }, .{ -1, 1 }, .{ 0, 1 },
];
+[ ] :UnaryFieldAccessIsGross
List of things to change:
[X] Currently, there is no way to use the initialized members of a structure without using a struct literal.
NODE(Dereference) \
NODE(ArrayAccess) \
NODE(FieldAccess) \
+ NODE(UnaryFieldAccess) \
NODE(SizeOf) \
NODE(AlignOf) \
NODE(FileContents) \
Ast_Kind_Array_Access,
Ast_Kind_Slice,
Ast_Kind_Field_Access,
+ Ast_Kind_Unary_Field_Access,
Ast_Kind_Pipe,
Ast_Kind_Method_Call,
Ast_Kind_Range_Literal,
struct AstSizeOf { AstTyped_base; AstType *so_ast_type; Type *so_type; u64 size; };
struct AstAlignOf { AstTyped_base; AstType *ao_ast_type; Type *ao_type; u64 alignment; };
struct AstFileContents { AstTyped_base; OnyxToken *filename; u32 addr, size; };
+struct AstUnaryFieldAccess {
+ AstTyped_base;
+
+ // "token" represents the field. This does not need an "offset" or an "index"
+ // because this node is meant to be replaced.
+};
struct AstStructLiteral {
AstTyped_base;
stencilOp(fail, zfail, mask) { gl.stencilOp(fail, zfail, mask); },
stencilOpSeparate(face, fail, zfail, zpass) { gl.stencilOpSeparate(face, fail, zfail, zpass); },
texImage2D(target, level, internalforamt, width, height, border, format, type, pixels, pixelslen) {
- const data = new DataView(window.ONYX_MEMORY.buffer, pixels, pixelslen);
+ const data = new Uint8Array(window.ONYX_MEMORY.buffer, pixels, pixelslen);
gl.texImage2D(target, level, internalforamt, width, height, border, format, type, data);
},
texParameterf(target, pname, param) { gl.texParameterf(target, pname, param); },
"RETURN",
"ADDRESS OF",
"DEREFERENCE",
- "ARRAY_ACCESS",
+ "ARRAY ACCESS",
"SLICE",
- "FIELD_ACCESS",
+ "FIELD ACCESS",
+ "UNARY FIELD ACCESS"
"PIPE",
"METHOD_CALL",
"RANGE",
// NOTE: Returns 0 if it was not possible to make the types compatible.
b32 type_check_or_auto_cast(AstTyped** pnode, Type* type) {
AstTyped* node = *pnode;
- assert(type != NULL);
- assert(node != NULL);
+ if (type == NULL) return 0;
+ if (node == NULL) return 0;
if (node_is_type((AstNode *) node)) return 0;
return 1;
}
+ if (node->kind == Ast_Kind_Unary_Field_Access) {
+ AstType* ast_type = type->ast_type;
+ AstNode* resolved = try_symbol_resolve_from_node((AstNode *) ast_type, node->token);
+ if (resolved == NULL) return 0;
+
+ *pnode = (AstTyped *) resolved;
+ return 1;
+ }
+
if (node->kind == Ast_Kind_Overloaded_Function) {
AstTyped* func = find_matching_overload_by_type(((AstOverloadedFunction *) node)->overloads, type);
if (func == NULL) return 0;
if (switchnode->assignment != NULL) CHECK(statement, (AstNode **) &switchnode->assignment);
CHECK(expression, &switchnode->expr);
- resolve_expression_type(switchnode->expr);
+ Type* resolved_expr_type = resolve_expression_type(switchnode->expr);
if (!type_is_integer(switchnode->expr->type) && switchnode->expr->type->kind != Type_Kind_Enum) {
onyx_report_error(switchnode->expr->token->pos, "expected integer or enum type for switch expression");
return Check_Error;
bh_arr_each(AstTyped *, value, sc->values) {
CHECK(expression, value);
+ // :UnaryFieldAccessIsGross
+ if ((*value)->kind == Ast_Kind_Unary_Field_Access) {
+ type_check_or_auto_cast(value, resolved_expr_type);
+ }
+
if ((*value)->kind == Ast_Kind_Range_Literal) {
AstRangeLiteral* rl = (AstRangeLiteral *) (*value);
resolve_expression_type(rl->low);
CheckStatus check_binaryop_compare(AstBinaryOp** pbinop) {
AstBinaryOp* binop = *pbinop;
+ // :UnaryFieldAccessIsGross
+ if (binop->left->kind == Ast_Kind_Unary_Field_Access || binop->right->kind == Ast_Kind_Unary_Field_Access) {
+ if (type_check_or_auto_cast(&binop->left, binop->right->type));
+ else if (type_check_or_auto_cast(&binop->right, binop->left->type));
+ else {
+ report_bad_binaryop(binop);
+ return Check_Error;
+ }
+
+ binop->type = &basic_types[Basic_Kind_Bool];
+ return Check_Success;
+ }
+
if ( type_is_structlike_strict(binop->left->type)
|| type_is_structlike_strict(binop->right->type)) {
report_bad_binaryop(binop);
if (ltype->kind == Type_Kind_Pointer) ltype = &basic_types[Basic_Kind_Rawptr];
if (rtype->kind == Type_Kind_Pointer) rtype = &basic_types[Basic_Kind_Rawptr];
-
if (!types_are_compatible(ltype, rtype)) {
b32 left_ac = node_is_auto_cast((AstNode *) binop->left);
b32 right_ac = node_is_auto_cast((AstNode *) binop->right);
case Ast_Kind_Polymorphic_Proc: break;
case Ast_Kind_Package: break;
case Ast_Kind_Error: break;
+ case Ast_Kind_Unary_Field_Access: break;
// NOTE: The only way to have an Intrinsic_Call node is to have gone through the
// checking of a call node at least once.
// Things that need to be cleaned up in the parser:
// - control block local variables should be more extensible and reuse more code
-// - package name parsing
#include "onyxlex.h"
#include "onyxerrors.h"
static AstNumLit* parse_float_literal(OnyxParser* parser);
static b32 parse_possible_struct_literal(OnyxParser* parser, AstTyped* left, AstTyped** ret);
static b32 parse_possible_array_literal(OnyxParser* parser, AstTyped* left, AstTyped** ret);
+static b32 parse_possible_unary_field_access(OnyxParser* parser, AstTyped** ret);
static void parse_arguments(OnyxParser* parser, TokenType end_token, Arguments* args);
static AstTyped* parse_factor(OnyxParser* parser);
static AstTyped* parse_compound_assignment(OnyxParser* parser, AstTyped* lhs);
return 1;
}
+static b32 parse_possible_unary_field_access(OnyxParser* parser, AstTyped** ret) {
+ if (!next_tokens_are(parser, 2, '.', Token_Type_Symbol)) return 0;
+
+ AstUnaryFieldAccess* ufl = make_node(AstUnaryFieldAccess, Ast_Kind_Unary_Field_Access);
+ expect_token(parser, '.');
+ ufl->token = expect_token(parser, Token_Type_Symbol);
+
+ *ret = (AstTyped *) ufl;
+ return 1;
+}
+
static void parse_arguments(OnyxParser* parser, TokenType end_token, Arguments* args) {
while (!consume_token_if_next(parser, end_token)) {
if (parser->hit_unexpected_token) return;
case '.': {
if (parse_possible_struct_literal(parser, NULL, &retval)) return retval;
if (parse_possible_array_literal(parser, NULL, &retval)) return retval;
+ if (parse_possible_unary_field_access(parser, &retval)) return retval;
goto no_match;
}