Commit 1223ae43 authored by Mol Thomas Folkert's avatar Mol Thomas Folkert
Browse files

rudimentary generation of zig code for testing

parent c304af5e
/// Header to be included in source, verbatim
/// No arguments. (Do NOT use formatted print.)
const C_HEADER =
/// No arguments.
pub const C_HEADER =
\\#include <stdio.h>
\\#include <stdint.h>
\\#include <time.h>
\\
\\
;
const ZIG_HEADER =
pub const ZIG_HEADER =
\\const std = @import("std");
\\const ctime = @cImport({
\\const ctime = @cImport({{
\\ @cInclude("time.h");
\\});
\\}});
\\
\\
;
/// General loop template used in below templates
/// Argument index:
/// 0 (string) = general type;
const C_GENERAL_LOOP =
pub const C_GENERAL_LOOP =
\\ {0s} _acc = 0;
\\ for ({0s} i = _lo; i < _hi; ++i)
\\ _acc += _arr[i];
\\
;
const ZIG_GENERAL_LOOP =
pub const ZIG_GENERAL_LOOP =
\\ var _acc: {0s} = 0;
\\ var i: usize = _lo;
\\ var i: usize = @intCast(usize, _lo);
\\ while (i < _hi) : (i += 1) {{
\\ _acc += _arr[i];
\\ }}
......@@ -38,112 +40,118 @@ const ZIG_GENERAL_LOOP =
/// Argument index:
/// 0 (string) = general type, 1 (string) = function name
/// 2 (int) = array size, 3 (string) = array
const C_COMPTIME_LOOP_TEMPLATE =
pub const C_COMPTIME_LOOP_TEMPLATE =
\\{0s} {1s}() {{
\\ {0s} _lo = 0;
\\ {0s} _hi = {2i};
\\ {0s} _arr[{2i}] = {3s};
\\ {0s} _hi = {2d};
\\ {0s} _arr[{2d}] = {3s};
\\
++ C_GENERAL_LOOP ++
\\ return _acc;
\\}}
\\
\\
;
const ZIG_COMPTIME_LOOP_TEMPPLATE =
pub const ZIG_COMPTIME_LOOP_TEMPLATE =
\\fn {1s}() {0s} {{
\\ const _lo: {0s} = 0;
\\ const _hi: {0s} = {2i};
\\ const _arr = [_]{2i}{3i};
\\ const _hi: {0s} = {2d};
\\ const _arr = [_]{0s}{3s};
\\
++ ZIG_GENERAL_LOOP ++
\\ return _acc;
\\}}
\\
\\
;
/// Loop testing template with volatile values of hi and arr
/// Argument index:
/// 0 (string) = general type, 1 (string) = function name
/// 2 (int) = array size, 3 (string) = array
const C_VOLATILE_LOOP_TEMPLATE =
pub const C_VOLATILE_LOOP_TEMPLATE =
\\{0s} {1s}() {{
\\ {0s} _lo = 0;
\\ volatile {0s} _hi = {2i};
\\ volatile {0s} _arr[{2i}] = {3s};
\\ volatile {0s} _hi = {2d};
\\ volatile {0s} _arr[{2d}] = {3s};
\\
++ C_GENERAL_LOOP ++
\\ return _acc;
\\}}
\\
\\
;
// Can not use ZIG_GENERAL_LOOP because of the pointer syntax used.
const ZIG_VOLATILE_LOOP_TEMPLATE =
pub const ZIG_VOLATILE_LOOP_TEMPLATE =
\\fn {1s}() {0s} {{
\\ const _lo: {0s} = 0;
\\ var _hi: {0s} = {2i};
\\ var _hi: {0s} = {2d};
\\ var _hi_p: *volatile {0s} = &_hi;
\\ var _arr = [_]{0s}{3i};
\\ var _arr_p = []volatile {0s} = &_arr;
\\ var _arr = [_]{0s}{3s};
\\ var _arr_p: []volatile {0s} = &_arr;
\\
\\ var _acc: {0s} = 0;
\\ var i: usize = _lo;
\\ var i: usize = @intCast(usize, _lo);
\\ while (i < _hi_p.*) : (i += 1) {{
\\ _acc += _arr_p[i];
\\ }}
\\ return _acc;
\\}}
\\
\\
;
/// Loop testing template with passed pointers
/// Argument index:
/// 0 (string) = general type, 1 (string) = function name
/// 2 (int) = array size, 3 (string) = array
const C_PASSED_LOOP_TEMPLATE =
\\{0s} _internal_passed_p({0s} _lo, {0s} *_hi, {0s} []* _arr) {{
pub const C_PASSED_LOOP_TEMPLATE =
\\{0s} _internal_passed_p({0s} _lo, {0s} *_hi, {0s} []_arr) {{
\\ {0s} _acc = 0;
\\ for ({0s} i = _lo; i < *_hi, ++i) {{
\\ _acc += (*_arr)[i];
\\ _acc += _arr[i];
\\ return _acc;
\\}}
\\
\\{0s} {1s}() {{
\\ {0s} _lo = 0;
\\ {0s} _hi = {2i};
\\ {0s} _arr[{2i}] = {3s};
\\ return _internal_passed_p(_lo, &_hi, &_arr);
\\ {0s} _hi = {2d};
\\ {0s} _arr[{2d}] = {3s};
\\ return _internal_passed_p(_lo, &_hi, _arr);
\\}}
\\
\\
;
const ZIG_PASSED_LOOP_TEMPLATE =
\\fn _internal_passed_p(_lo: {0s}, _hi: *{0s}, _arr: *[]{0s}) {{
pub const ZIG_PASSED_LOOP_TEMPLATE =
\\fn _internal_passed_p(_lo: {0s}, _hi: *{0s}, _arr: [*]const {0s}) {0s} {{
\\ var _acc: {0s} = 0;
\\ var i: usize = _lo;
\\ var i: usize = @intCast(usize, _lo);
\\ while (i < _hi.*) : (i += 1) {{
\\ _acc += _arr.*[i];
\\ _acc += _arr[i];
\\ }}
\\ return _acc;
\\}}
\\
\\fn {1s}() {0s} {{
\\ const _lo: {0s} = 0;
\\ var _hi: {0s} = {2i};
\\ var _arr = [_]{0s}{3i};
\\ return _internal_passed_p(_lo, &_hi, &_arr);
\\ var _hi: {0s} = {2d};
\\ var _arr: [*]const {0s} = &[{2d}]{0s}{3s};
\\ return _internal_passed_p(_lo, &_hi, _arr);
\\}}
\\
\\
;
/// Loop testing template with values returned from passed function pointers
/// Argument index:
/// 0 (string) = general type, 1 (string) = function name
/// 2 (int) = array size, 3 (string) = array
const C_FUNCTION_LOOP_TEMPLATE =
pub const C_FUNCTION_LOOP_TEMPLATE =
\\{0s} _hi_fn() {{
\\ return {2s};
\\ return {2d};
\\}}
\\
\\{0s} _fn_arr[{0s}] = {3s};
......@@ -164,24 +172,25 @@ const C_FUNCTION_LOOP_TEMPLATE =
\\ return _internal_passed_fn(&_hi_fn, &_arr_fn);
\\}}
\\
\\
;
const ZIG_FUNCTION_LOOP_TEMPLATE =
pub const ZIG_FUNCTION_LOOP_TEMPLATE =
\\fn _hi_fn() {0s} {{
\\ return {2s};
\\ return {2d};
\\}}
\\
\\var _fn_arr = [_]{0s}{3i};
\\var _fn_arr: [*]const {0s} = &[{2d}]{0s}{3s};
\\
\\fn _arr_fn() *{0s} {{
\\fn _arr_fn() [*]const {0s} {{
\\ return _fn_arr;
\\}}
\\
\\fn _internal_passed_fn(_hi_fn_p: fn () {0s}, _arr_fn_p: fn () *{0s}) {0s} {{
\\fn _internal_passed_fn(_hi_fn_p: fn () {0s}, _arr_fn_p: fn () [*]const {0s}) {0s} {{
\\ const lo: {0s} = 0;
\\ var _acc: {0s} = 0;
\\ var i: {0s} = lo;
\\ while (i < _hi_fn_p()) : (i += 1) {
\\ var i: usize = @intCast(usize, lo);
\\ while (i < _hi_fn_p()) : (i += 1) {{
\\ _acc += _arr_fn_p()[i];
\\ }}
\\ return _acc;
......@@ -191,13 +200,14 @@ const ZIG_FUNCTION_LOOP_TEMPLATE =
\\ return _internal_passed_fn(_hi_fn, _arr_fn);
\\}}
\\
\\
;
/// General testing template for running a function and printing its duration.
/// Include inside a function body.
/// Argument index:
/// 0 (string) = function name (to test)
const C_TEST_FUNCTION_TEMPLATE =
pub const C_TEST_FUNCTION_TEMPLATE =
\\ struct timespec {0s}_start;
\\ struct timespec {0s}_end;
\\ clock_gettime(CLOCK_MONOTONIC_RAW, &{0s}_start);
......@@ -206,17 +216,19 @@ const C_TEST_FUNCTION_TEMPLATE =
\\ double {0s}_duration = {0s}_end.tv_nsec - {0s}_start.tv_nsec;
\\ printf("{0s} done. Time: %d\n.", {0s}_duration);
\\
\\
;
const ZIG_TEST_FUNCTION_TEMPLATE =
\\ const stdout = std.io.getStdOut().writer();
pub const ZIG_TEST_FUNCTION_TEMPLATE =
\\ const {0s}_stdout = std.io.getStdOut().writer();
\\
\\ var {0s}_start: ctime.timespec = .{{.tv_sec = 0, .tv_nsec = 0}};
\\ var {0s}_end: ctime.timespec = .{{.tv_sec = 0, .tv_nsec = 0}};
\\ _ = ctime.clock_gettime(ctime.CLOCK_MONOTONIC_RAW, &{0s}_start);
\\ _ = {0s}();
\\ _ = ctime.clock_gettime(ctime.CLOCK_MONOTONIC_RAW, &{0s}_end);
\\ var {0s}_duration: c_long = {0s}_end.tv_nsec - {0s}_start.tv_nsec;
\\ try {0s}_stdout.print("{0s} done. {{d}} nanoseconds\n", .{{{0s}_duration}});
\\
\\ ctime.timespec {0s}_start;
\\ ctime.timespec {0s}_end;
\\ ctime.clock_gettime(ctime.CLOCK_MONOTONIC_RAW, &{0s}_start);
\\ {0s}();
\\ ctime.clock_gettime(ctime.CLOCK_MONOTONIC_RAW, &{0s}_end);
\\ var {0s}_duration: f64 = {0s}_end.tv_nsec - {0s}_start.tv_nsec;
\\ try stdout.print("{0s} done. Time: %d\n.", {0s}_duration);
\\
;
const std = @import("std");
const templates = @import("template_strings.zig");
const fs = std.fs;
const c_output = "c_generated_tests.c";
const zig_output = "z_generated_tests.zig";
const c_i32 = "int32_t";
const zig_i32 = "i32";
const simple_array = "{1, 2, 3, 4, 5}";
fn create_array_string() *const [15:0]u8 {
return simple_array;
}
const comptime_args = .{ zig_i32, "comptime_loop", 5, simple_array };
const volatile_args = .{ zig_i32, "volatile_loop", 5, simple_array };
const passed_args = .{ zig_i32, "passed_loop", 5, simple_array };
const function_args = .{ zig_i32, "function_loop", 5, simple_array };
fn write_zig_tests() !void {
const file = try fs.cwd().createFile(zig_output, .{});
defer file.close();
const writer = fs.File.writer(file);
try writer.print(templates.ZIG_HEADER, .{});
try writer.print(templates.ZIG_COMPTIME_LOOP_TEMPLATE, comptime_args);
try writer.print(templates.ZIG_VOLATILE_LOOP_TEMPLATE, volatile_args);
try writer.print(templates.ZIG_PASSED_LOOP_TEMPLATE, passed_args);
try writer.print(templates.ZIG_FUNCTION_LOOP_TEMPLATE, function_args);
try writer.print("pub fn main() !void {{\n", .{});
try writer.print(templates.ZIG_TEST_FUNCTION_TEMPLATE, .{"comptime_loop"});
try writer.print(templates.ZIG_TEST_FUNCTION_TEMPLATE, .{"volatile_loop"});
try writer.print(templates.ZIG_TEST_FUNCTION_TEMPLATE, .{"passed_loop"});
try writer.print(templates.ZIG_TEST_FUNCTION_TEMPLATE, .{"function_loop"});
try writer.print("}}\n", .{});
}
pub fn main() !void {
try write_zig_tests();
}
const std = @import("std");
const ctime = @cImport({
@cInclude("time.h");
});
fn comptime_loop() i32 {
const _lo: i32 = 0;
const _hi: i32 = 5;
const _arr = [_]i32{1, 2, 3, 4, 5};
var _acc: i32 = 0;
var i: usize = @intCast(usize, _lo);
while (i < _hi) : (i += 1) {
_acc += _arr[i];
}
return _acc;
}
fn volatile_loop() i32 {
const _lo: i32 = 0;
var _hi: i32 = 5;
var _hi_p: *volatile i32 = &_hi;
var _arr = [_]i32{1, 2, 3, 4, 5};
var _arr_p: []volatile i32 = &_arr;
var _acc: i32 = 0;
var i: usize = @intCast(usize, _lo);
while (i < _hi_p.*) : (i += 1) {
_acc += _arr_p[i];
}
return _acc;
}
fn _internal_passed_p(_lo: i32, _hi: *i32, _arr: [*]const i32) i32 {
var _acc: i32 = 0;
var i: usize = @intCast(usize, _lo);
while (i < _hi.*) : (i += 1) {
_acc += _arr[i];
}
return _acc;
}
fn passed_loop() i32 {
const _lo: i32 = 0;
var _hi: i32 = 5;
var _arr: [*]const i32 = &[5]i32{1, 2, 3, 4, 5};
return _internal_passed_p(_lo, &_hi, _arr);
}
fn _hi_fn() i32 {
return 5;
}
var _fn_arr: [*]const i32 = &[5]i32{1, 2, 3, 4, 5};
fn _arr_fn() [*]const i32 {
return _fn_arr;
}
fn _internal_passed_fn(_hi_fn_p: fn () i32, _arr_fn_p: fn () [*]const i32) i32 {
const lo: i32 = 0;
var _acc: i32 = 0;
var i: usize = @intCast(usize, lo);
while (i < _hi_fn_p()) : (i += 1) {
_acc += _arr_fn_p()[i];
}
return _acc;
}
fn function_loop() i32 {
return _internal_passed_fn(_hi_fn, _arr_fn);
}
pub fn main() !void {
const comptime_loop_stdout = std.io.getStdOut().writer();
var comptime_loop_start: ctime.timespec = .{.tv_sec = 0, .tv_nsec = 0};
var comptime_loop_end: ctime.timespec = .{.tv_sec = 0, .tv_nsec = 0};
_ = ctime.clock_gettime(ctime.CLOCK_MONOTONIC_RAW, &comptime_loop_start);
_ = comptime_loop();
_ = ctime.clock_gettime(ctime.CLOCK_MONOTONIC_RAW, &comptime_loop_end);
var comptime_loop_duration: c_long = comptime_loop_end.tv_nsec - comptime_loop_start.tv_nsec;
try comptime_loop_stdout.print("comptime_loop done. {d} nanoseconds\n", .{comptime_loop_duration});
const volatile_loop_stdout = std.io.getStdOut().writer();
var volatile_loop_start: ctime.timespec = .{.tv_sec = 0, .tv_nsec = 0};
var volatile_loop_end: ctime.timespec = .{.tv_sec = 0, .tv_nsec = 0};
_ = ctime.clock_gettime(ctime.CLOCK_MONOTONIC_RAW, &volatile_loop_start);
_ = volatile_loop();
_ = ctime.clock_gettime(ctime.CLOCK_MONOTONIC_RAW, &volatile_loop_end);
var volatile_loop_duration: c_long = volatile_loop_end.tv_nsec - volatile_loop_start.tv_nsec;
try volatile_loop_stdout.print("volatile_loop done. {d} nanoseconds\n", .{volatile_loop_duration});
const passed_loop_stdout = std.io.getStdOut().writer();
var passed_loop_start: ctime.timespec = .{.tv_sec = 0, .tv_nsec = 0};
var passed_loop_end: ctime.timespec = .{.tv_sec = 0, .tv_nsec = 0};
_ = ctime.clock_gettime(ctime.CLOCK_MONOTONIC_RAW, &passed_loop_start);
_ = passed_loop();
_ = ctime.clock_gettime(ctime.CLOCK_MONOTONIC_RAW, &passed_loop_end);
var passed_loop_duration: c_long = passed_loop_end.tv_nsec - passed_loop_start.tv_nsec;
try passed_loop_stdout.print("passed_loop done. {d} nanoseconds\n", .{passed_loop_duration});
const function_loop_stdout = std.io.getStdOut().writer();
var function_loop_start: ctime.timespec = .{.tv_sec = 0, .tv_nsec = 0};
var function_loop_end: ctime.timespec = .{.tv_sec = 0, .tv_nsec = 0};
_ = ctime.clock_gettime(ctime.CLOCK_MONOTONIC_RAW, &function_loop_start);
_ = function_loop();
_ = ctime.clock_gettime(ctime.CLOCK_MONOTONIC_RAW, &function_loop_end);
var function_loop_duration: c_long = function_loop_end.tv_nsec - function_loop_start.tv_nsec;
try function_loop_stdout.print("function_loop done. {d} nanoseconds\n", .{function_loop_duration});
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment