mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
translate-c-2 array access
This commit is contained in:
parent
cf7a5b7a4a
commit
c2666c48a4
@ -28,6 +28,8 @@ pub const CToken = struct {
|
||||
Comma,
|
||||
Fn,
|
||||
Arrow,
|
||||
LBrace,
|
||||
RBrace,
|
||||
};
|
||||
|
||||
pub const NumLitSuffix = enum {
|
||||
@ -289,6 +291,14 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
|
||||
result.id = .Comma;
|
||||
state = .Done;
|
||||
},
|
||||
'[' => {
|
||||
result.id = .LBrace;
|
||||
state = .Done;
|
||||
},
|
||||
']' => {
|
||||
result.id = .RBrace;
|
||||
state = .Done;
|
||||
},
|
||||
else => return error.TokenizingFailed,
|
||||
}
|
||||
},
|
||||
|
||||
@ -1102,3 +1102,6 @@ pub extern fn ZigClangMemberExpr_getBase(*const ZigClangMemberExpr) *const ZigCl
|
||||
pub extern fn ZigClangMemberExpr_isArrow(*const ZigClangMemberExpr) bool;
|
||||
pub extern fn ZigClangMemberExpr_getMemberDecl(*const ZigClangMemberExpr) *const ZigClangValueDecl;
|
||||
|
||||
pub extern fn ZigClangArraySubscriptExpr_getBase(*const ZigClangArraySubscriptExpr) *const ZigClangExpr;
|
||||
pub extern fn ZigClangArraySubscriptExpr_getIdx(*const ZigClangArraySubscriptExpr) *const ZigClangExpr;
|
||||
|
||||
|
||||
@ -850,6 +850,7 @@ fn transStmt(
|
||||
.CharacterLiteralClass => return transCharLiteral(rp, scope, @ptrCast(*const ZigClangCharacterLiteral, stmt), result_used),
|
||||
.StmtExprClass => return transStmtExpr(rp, scope, @ptrCast(*const ZigClangStmtExpr, stmt), result_used),
|
||||
.MemberExprClass => return transMemberExpr(rp, scope, @ptrCast(*const ZigClangMemberExpr, stmt), result_used),
|
||||
.ArraySubscriptExprClass => return transArrayAccess(rp, scope, @ptrCast(*const ZigClangArraySubscriptExpr, stmt), result_used),
|
||||
else => {
|
||||
return revertAndWarn(
|
||||
rp,
|
||||
@ -1523,7 +1524,7 @@ fn transInitListExpr(
|
||||
var cat_tok: ast.TokenIndex = undefined;
|
||||
if (init_count != 0) {
|
||||
const dot_tok = try appendToken(rp.c, .Period, ".");
|
||||
init_node = try transCreateNodeArrayInitializer(rp.c, dot_tok);
|
||||
init_node = try transCreateNodeContainerInitializer(rp.c, dot_tok);
|
||||
var i: c_uint = 0;
|
||||
while (i < init_count) : (i += 1) {
|
||||
const elem_expr = ZigClangInitListExpr_getInit(expr, i);
|
||||
@ -1538,7 +1539,7 @@ fn transInitListExpr(
|
||||
}
|
||||
|
||||
const dot_tok = try appendToken(rp.c, .Period, ".");
|
||||
var filler_init_node = try transCreateNodeArrayInitializer(rp.c, dot_tok);
|
||||
var filler_init_node = try transCreateNodeContainerInitializer(rp.c, dot_tok);
|
||||
const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr);
|
||||
try filler_init_node.op.ArrayInitializer.push(try transExpr(rp, scope, filler_val_expr, .used, .r_value));
|
||||
filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}");
|
||||
@ -1995,6 +1996,14 @@ fn transMemberExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangMemberE
|
||||
return maybeSuppressResult(rp, scope, result_used, node);
|
||||
}
|
||||
|
||||
fn transArrayAccess(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangArraySubscriptExpr, result_used: ResultUsed) TransError!*ast.Node {
|
||||
const container_node = try transExpr(rp, scope, ZigClangArraySubscriptExpr_getBase(stmt), .used, .r_value);
|
||||
const node = try transCreateNodeArrayAccess(rp.c, container_node);
|
||||
node.op.ArrayAccess = try transExpr(rp, scope, ZigClangArraySubscriptExpr_getIdx(stmt), .used, .r_value);
|
||||
node.rtoken = try appendToken(rp.c, .RBrace, "]");
|
||||
return maybeSuppressResult(rp, scope, result_used, &node.base);
|
||||
}
|
||||
|
||||
fn transCPtrCast(
|
||||
rp: RestorePoint,
|
||||
loc: ZigClangSourceLocation,
|
||||
@ -2643,7 +2652,7 @@ fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node {
|
||||
return &node.base;
|
||||
}
|
||||
|
||||
fn transCreateNodeArrayInitializer(c: *Context, dot_tok: ast.TokenIndex) !*ast.Node.SuffixOp {
|
||||
fn transCreateNodeContainerInitializer(c: *Context, dot_tok: ast.TokenIndex) !*ast.Node.SuffixOp {
|
||||
_ = try appendToken(c, .LBrace, "{");
|
||||
const node = try c.a().create(ast.Node.SuffixOp);
|
||||
node.* = ast.Node.SuffixOp{
|
||||
@ -2972,6 +2981,19 @@ fn transCreateNodePtrDeref(c: *Context, lhs: *ast.Node) !*ast.Node {
|
||||
return &node.base;
|
||||
}
|
||||
|
||||
fn transCreateNodeArrayAccess(c: *Context, lhs: *ast.Node) !*ast.Node.SuffixOp {
|
||||
_ = try appendToken(c, .LBrace, "[");
|
||||
const node = try c.a().create(ast.Node.SuffixOp);
|
||||
node.* = .{
|
||||
.lhs = .{ .node = lhs },
|
||||
.op = .{
|
||||
.ArrayAccess = undefined,
|
||||
},
|
||||
.rtoken = undefined,
|
||||
};
|
||||
return node;
|
||||
}
|
||||
|
||||
const RestorePoint = struct {
|
||||
c: *Context,
|
||||
token_index: ast.TokenIndex,
|
||||
@ -3869,26 +3891,14 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
|
||||
.Dot => {
|
||||
const name_tok = it.next().?;
|
||||
if (name_tok.id != .Identifier)
|
||||
return revertAndWarn(
|
||||
rp,
|
||||
error.ParseError,
|
||||
source_loc,
|
||||
"unable to translate C expr",
|
||||
.{},
|
||||
);
|
||||
return error.ParseError;
|
||||
|
||||
node = try transCreateNodeFieldAccess(rp.c, node, name_tok.bytes);
|
||||
},
|
||||
.Arrow => {
|
||||
const name_tok = it.next().?;
|
||||
if (name_tok.id != .Identifier)
|
||||
return revertAndWarn(
|
||||
rp,
|
||||
error.ParseError,
|
||||
source_loc,
|
||||
"unable to translate C expr",
|
||||
.{},
|
||||
);
|
||||
return error.ParseError;
|
||||
|
||||
const deref = try transCreateNodePtrDeref(rp.c, node);
|
||||
node = try transCreateNodeFieldAccess(rp.c, deref, name_tok.bytes);
|
||||
@ -3929,6 +3939,14 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
|
||||
};
|
||||
node = &bitshift_node.base;
|
||||
},
|
||||
.LBrace => {
|
||||
const arr_node = try transCreateNodeArrayAccess(rp.c, node);
|
||||
arr_node.op.ArrayAccess = try parseCPrimaryExpr(rp, it, source_loc, scope);
|
||||
arr_node.rtoken = try appendToken(rp.c, .RBrace, "]");
|
||||
node = &arr_node.base;
|
||||
if (it.next().?.id != .RBrace)
|
||||
return error.ParseError;
|
||||
},
|
||||
else => {
|
||||
_ = it.prev();
|
||||
return node;
|
||||
|
||||
@ -1523,6 +1523,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub const ARROW = a.*.b;
|
||||
});
|
||||
|
||||
cases.add_2("array access",
|
||||
\\#define ACCESS array[2]
|
||||
\\int array[100] = {};
|
||||
\\int foo(int index) {
|
||||
\\ return array[index];
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export var array: [100]c_int = .{0} ** 100;
|
||||
\\pub export fn foo(index: c_int) c_int {
|
||||
\\ return array[index];
|
||||
\\}
|
||||
,
|
||||
\\pub const ACCESS = array[2];
|
||||
});
|
||||
|
||||
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
|
||||
|
||||
cases.addAllowWarnings("simple data types",
|
||||
@ -1731,18 +1746,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC("array access",
|
||||
\\int array[100];
|
||||
\\int foo(int index) {
|
||||
\\ return array[index];
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub var array: [100]c_int = undefined;
|
||||
\\pub export fn foo(index: c_int) c_int {
|
||||
\\ return array[index];
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC("sizeof",
|
||||
\\#include <stddef.h>
|
||||
\\size_t size_of(void) {
|
||||
@ -2656,4 +2659,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ return foo.*.field;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC("array access",
|
||||
\\int array[100];
|
||||
\\int foo(int index) {
|
||||
\\ return array[index];
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub var array: [100]c_int = undefined;
|
||||
\\pub export fn foo(index: c_int) c_int {
|
||||
\\ return array[index];
|
||||
\\}
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user