added the first C exercise
This commit is contained in:
parent
0f42850f7e
commit
4cf3bd63a2
3 changed files with 87 additions and 0 deletions
14
build.zig
14
build.zig
|
@ -31,6 +31,10 @@ const Exercise = struct {
|
||||||
/// We need to keep track of this, so we compile without the self hosted compiler
|
/// We need to keep track of this, so we compile without the self hosted compiler
|
||||||
@"async": bool = false,
|
@"async": bool = false,
|
||||||
|
|
||||||
|
/// This exercise makes use of C functions
|
||||||
|
/// We need to keep track of this, so we compile with libc
|
||||||
|
C: bool = false,
|
||||||
|
|
||||||
/// Returns the name of the main file with .zig stripped.
|
/// Returns the name of the main file with .zig stripped.
|
||||||
pub fn baseName(self: Exercise) []const u8 {
|
pub fn baseName(self: Exercise) []const u8 {
|
||||||
assert(std.mem.endsWith(u8, self.main_file, ".zig"));
|
assert(std.mem.endsWith(u8, self.main_file, ".zig"));
|
||||||
|
@ -461,6 +465,11 @@ const exercises = [_]Exercise{
|
||||||
// .output = "ABCDEF",
|
// .output = "ABCDEF",
|
||||||
// .@"async" = true,
|
// .@"async" = true,
|
||||||
// },
|
// },
|
||||||
|
.{
|
||||||
|
.main_file = "093_hello_c.zig",
|
||||||
|
.output = "Hello C from Zig! - C result ist 17 chars",
|
||||||
|
.C = true,
|
||||||
|
},
|
||||||
.{
|
.{
|
||||||
.main_file = "999_the_end.zig",
|
.main_file = "999_the_end.zig",
|
||||||
.output = "\nThis is the end for now!\nWe hope you had fun and were able to learn a lot, so visit us again when the next exercises are available.",
|
.output = "\nThis is the end for now!\nWe hope you had fun and were able to learn a lot, so visit us again when the next exercises are available.",
|
||||||
|
@ -725,6 +734,11 @@ const ZiglingStep = struct {
|
||||||
// zig_args.append("-fstage1") catch unreachable;
|
// zig_args.append("-fstage1") catch unreachable;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// Enable C support for exercises that use C functions
|
||||||
|
if (self.exercise.C) {
|
||||||
|
zig_args.append("-lc") catch unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
if (builder.color != .auto) {
|
if (builder.color != .auto) {
|
||||||
zig_args.append("--color") catch unreachable;
|
zig_args.append("--color") catch unreachable;
|
||||||
zig_args.append(@tagName(builder.color)) catch unreachable;
|
zig_args.append(@tagName(builder.color)) catch unreachable;
|
||||||
|
|
69
exercises/093_hello_c.zig
Normal file
69
exercises/093_hello_c.zig
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
//
|
||||||
|
// When Andrew Kelley announced the idea of a new programming language
|
||||||
|
// - namely Zig - in his blog on February 8, 2016, he also immediately
|
||||||
|
// stated his ambitious goal: to replace the C language!
|
||||||
|
//
|
||||||
|
// In order to be able to achieve this goal at all, Zig should be
|
||||||
|
// as compatible as possible with its "predecessor".
|
||||||
|
// Only if it is possible to exchange individual modules in existing
|
||||||
|
// C programs without having to use complicated wrappers,
|
||||||
|
// the undertaking has a chance of success.
|
||||||
|
//
|
||||||
|
// So it is not surprising that calling C functions and vice versa
|
||||||
|
// is extremely "smooth".
|
||||||
|
//
|
||||||
|
// To call C functions in Zig, you only need to specify the library
|
||||||
|
// that contains said function. For this purpose there is a built-in
|
||||||
|
// function corresponding to the well-known @import():
|
||||||
|
//
|
||||||
|
// @cImport()
|
||||||
|
//
|
||||||
|
// All required libraries can now be included in the usual Zig notation:
|
||||||
|
//
|
||||||
|
// const c = @cImport({
|
||||||
|
// @cInclude("stdio.h");
|
||||||
|
// @cInclude("...");
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// Now a function can be called via the (in this example) constant 'c':
|
||||||
|
//
|
||||||
|
// c.puts("Hello world!");
|
||||||
|
//
|
||||||
|
// By the way, most C functions have return values in the form of an
|
||||||
|
// integer value. Errors can then be evaluated (return < 0) or other
|
||||||
|
// information can be obtained. For example, 'puts' returns the number
|
||||||
|
// of characters output.
|
||||||
|
//
|
||||||
|
// So that all this does not remain a dry theroy now, let's just start
|
||||||
|
// and call a C function out of Zig.
|
||||||
|
//
|
||||||
|
// our well-known "import" for Zig
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
// new the import for C
|
||||||
|
const c = @cImport({
|
||||||
|
|
||||||
|
// we use "standard input/output" from C
|
||||||
|
@cInclude("stdio.h");
|
||||||
|
});
|
||||||
|
|
||||||
|
pub fn main() void {
|
||||||
|
|
||||||
|
// In order to output a text that can be evaluated by the
|
||||||
|
// Zig Builder, we need to write it to the Error output.
|
||||||
|
// In Zig we do this with "std.debug.print" and in C we can
|
||||||
|
// specify the file to write to, i.e. "standard error (stderr)".
|
||||||
|
//
|
||||||
|
// Ups, something is wrong...
|
||||||
|
const c_res = fprintf(c.stderr, "Hello C from Zig!");
|
||||||
|
|
||||||
|
// let's see what the result from C is:
|
||||||
|
std.debug.print(" - C result ist {d} chars\n", .{c_res});
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Something must be considered when compiling with C functions.
|
||||||
|
// Namely that the Zig compiler knows that it should include
|
||||||
|
// corresponding libraries. For this purpose we call the compiler
|
||||||
|
// with the parameter "lc" for such a program,
|
||||||
|
// e.g. "zig run -lc hello_c.zig".
|
||||||
|
//
|
4
patches/patches/093_hello_c.patch
Normal file
4
patches/patches/093_hello_c.patch
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
58c58
|
||||||
|
< const c_res = fprintf(c.stderr, "Hello C from Zig!");
|
||||||
|
---
|
||||||
|
> const c_res = c.fprintf(c.stderr, "Hello C from Zig!");
|
Loading…
Reference in a new issue