Skip to content

Commit

Permalink
Added examples that can be run with zig build example -Dexample
Browse files Browse the repository at this point in the history
  • Loading branch information
Luukdegram committed Sep 1, 2020
1 parent edf11c0 commit 530342c
Show file tree
Hide file tree
Showing 12 changed files with 168 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.zig text=auto eol=lf
13 changes: 12 additions & 1 deletion build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,18 @@ pub fn build(b: *Builder) void {
const lib = b.addStaticLibrary("luf", "src/luf.zig");
lib.setBuildMode(mode);
lib.install();


var examples = b.addExecutable("example", "examples/example_runner.zig");
examples.setBuildMode(mode);
examples.addPackagePath("luf", "src/luf.zig");
const example_runner = examples.run();

const example = b.option([]const u8, "example", "The example to run (without .luf suffix)");

examples.addBuildOption(?[]const u8, "example", example);

const example_step = b.step("examples", "Runs an example using the -Dexample flag");
example_step.dependOn(&example_runner.step);

var main_tests = b.addTest("src/luf.zig");
main_tests.setBuildMode(mode);
Expand Down
9 changes: 9 additions & 0 deletions examples/arithmetic.luf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const x = 15
const y = 20

mut z = x + y
z = z << 1


//this allows example to print last value
z
8 changes: 8 additions & 0 deletions examples/enums.luf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const MyEnum = enum{
first_enum,
second_enum,
third_enum
}

//this allows example to print last value
MyEnum.third_enum
50 changes: 50 additions & 0 deletions examples/example_runner.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const std = @import("std");
const luf = @import("luf");

const example = @import("build_options").example;

pub fn main() !void {
if (example == null)
return std.debug.print(
"No example was provided, use -Dexample=example_name to run an example",
.{},
);

var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();

const allocator = &gpa.allocator;

const example_path = try std.fs.path.join(allocator, &[_][]const u8{
"examples",
example.?,
});
defer allocator.free(example_path);

const example_file = try std.mem.concat(allocator, u8, &[_][]const u8{
example_path,
".luf",
});
defer allocator.free(example_file);

const file = std.fs.cwd().openFile(example_file, .{}) catch |_| {
return std.debug.print("Example does not exist", .{});
};
defer file.close();

const size = try file.getEndPos();

const source = try file.readAllAlloc(allocator, size, size);
defer allocator.free(source);

const writer = std.io.getStdErr().writer();
var vm = luf.Vm.init(allocator);
defer vm.deinit();
vm.compileAndRun(source) catch |err| {
try vm.errors.write(source, writer);
return err;
};

try vm.peek().print(writer);
try writer.writeAll("\n");
}
8 changes: 8 additions & 0 deletions examples/function.luf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const sum = fn(a:int, b:int) int {
return a + b
}

const x: int = sum(5, 6)

//this allows example to print last value
x
12 changes: 12 additions & 0 deletions examples/if.luf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
mut x = 5

if (x == 4) {
x = 2
} else if (x == 3){
x = 1
} else {
x = 0
}

//this allows example to print last value
x
7 changes: 7 additions & 0 deletions examples/lists.luf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const list = []int{1,2,3}
const map = []string:int{"hello":1, "world":2}

const sum = map["hello"] + map["world"]

//this allows example to print last value
sum
18 changes: 18 additions & 0 deletions examples/loops.luf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const list = []int{1,2,3}
mut sum = 0
for(list) |element, index| {
sum += element + index
}

for(20..50) |i| {
sum += i
}

mut i = 0
while(i<10) {
sum += i
i+=1
}

//this allows example to print last value
sum
1 change: 1 addition & 0 deletions src/luf.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub const Lexer = @import("lexer.zig").Lexer;
pub const Token = @import("token.zig").Token;
pub const Vm = @import("vm.zig").Vm;

test "All tests" {
//_ = @import("eval.zig");
Expand Down
41 changes: 41 additions & 0 deletions src/value.zig
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,47 @@ pub const Value = union(Type) {
pub const List = std.ArrayListUnmanaged(*Value);
pub const Map = std.HashMapUnmanaged(*const Value, *Value, hash, eql, true);
pub const NativeFn = fn (vm: *@import("vm.zig").Vm, args: []*Value) anyerror!*Value;

/// Prints a `Value` to the given `writer`
pub fn print(self: *const Value, writer: anytype) @TypeOf(writer).Error!void {
switch (self.*) {
.integer => |int| try writer.print("{}", .{int}),
.boolean => |boolean| try writer.print("{}", .{boolean}),
.string => |string| try writer.writeAll(string),
.nil => |nil| try writer.writeAll("nil"),
.list => |list| {
try writer.writeAll("[");
for (list.items) |item, i| {
try item.print(writer);
if (i != list.items.len - 1)
try writer.writeAll(",\n");
}
try writer.writeAll("]\n");
},
.map => |map| {
try writer.writeAll("{");
for (map.entries.items) |item, i| {
try item.key.print(writer);
try writer.writeAll(":");
try item.value.print(writer);
if (i != map.items().len - 1)
try writer.writeAll(",\n");
}
try writer.writeAll("}\n");
},
.range => |range| try writer.print("{}..{}", .{ range.start, range.end }),
._enum => |enm| {
try writer.writeAll("{");
for (enm) |item, i| {
try writer.writeAll(item);
if (i != enm.len - 1)
try writer.writeAll(",\n");
}
try writer.writeAll("}\n");
},
else => try writer.writeAll("void"),
}
}
};

/// Scope maps identifiers to their names and can be used
Expand Down
4 changes: 1 addition & 3 deletions src/vm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ pub const Vm = struct {

/// Returns the previously popped `Value`
/// Note that this results in UB if the stack is empty.
fn peek(self: *Vm) *Value {
pub fn peek(self: *Vm) *Value {
return self.stack[self.sp];
}

Expand Down Expand Up @@ -706,7 +706,6 @@ pub const Vm = struct {

const last_ip = self.ip;
const last_sp = self.sp;

try self.run(code);

// Get all constants exposed by the source file
Expand Down Expand Up @@ -742,7 +741,6 @@ pub const Vm = struct {
fn loadModule(self: *Vm) Error!void {
const val = self.pop().?;
const name = val.unwrapAs(.string) orelse return self.fail("Expected a string");

const mod = self.imports.get(name) orelse blk: {
const imp = self.importModule(name) catch return self.fail("Could not import module");
try self.imports.put(name, imp);
Expand Down

0 comments on commit 530342c

Please sign in to comment.