translate-c-2 array access

This commit is contained in:
Vexu 2019-12-18 22:57:53 +02:00
parent cf7a5b7a4a
commit c2666c48a4
No known key found for this signature in database
GPG Key ID: 59AEB8936E16A6AC
4 changed files with 75 additions and 29 deletions

View File

@ -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,
}
},

View File

@ -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;

View File

@ -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;

View File

@ -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];
\\}
});
}