Skip to content

Commit

Permalink
Added another example, include Makefiles with examples and spec to te…
Browse files Browse the repository at this point in the history
…st examples
  • Loading branch information
singul4ri7y committed Aug 17, 2024
1 parent 9c3758b commit 58da3ab
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 13 deletions.
10 changes: 3 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,11 @@ PTLUA_LDLIBS = -llua -lm
# Compilation targets
# ===================

.PHONY: library examples tests all install uninstall clean
.PHONY: library tests all install uninstall clean

library: \
pt-lua

examples: library \
examples/fibonacci/fibonacci.so

tests: library \
spec/tracebacks/anon_lua/module.so \
spec/tracebacks/depth_recursion/module.so \
Expand All @@ -51,7 +48,7 @@ tests: library \
spec/tracebacks/multimod/module_b.so \
spec/tracebacks/singular/module.so

all: library examples tests
all: library tests

install: library
$(INSTALL_EXEC) pt-lua $(BINDIR)
Expand All @@ -62,15 +59,14 @@ uninstall:
rm -rf $(BINDIR)/pt-run

clean:
rm -rf pt-lua examples/*/*.so spec/tracebacks/*/*.so
rm -rf pt-run spec/tracebacks/*/*.so

%.so: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LIBFLAG) $< -o $@

pt-lua: pt-lua.c ptracer.h
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(PTLUA_LDFLAGS) $< -o $@ $(PTLUA_LDLIBS)

examples/fibonacci/fibonacci.so: examples/fibonacci/fibonacci.c ptracer.h
spec/tracebacks/anon_lua/module.so: spec/tracebacks/anon_lua/module.c ptracer.h
spec/tracebacks/depth_recursion/module.so: spec/tracebacks/depth_recursion/module.c ptracer.h
spec/tracebacks/dispatch/module.so: spec/tracebacks/dispatch/module.c ptracer.h
Expand Down
27 changes: 27 additions & 0 deletions examples/connected-components/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright (c) 2024, The Pallene Developers
# Pallene Tracer is licensed under the MIT license.
# Please refer to the LICENSE and AUTHORS files for details
# SPDX-License-Identifier: MIT

OUTPUT_FILE = component.so

CC = cc
CFLAGS = -O2 -std=c99 -pedantic -Wall -Wextra -Wformat-security
LIBFLAGS = -fPIC -shared

ifneq ($(findstring debug, $(MAKECMDGOALS)), )
CFLAGS += -DPT_DEBUG
endif

.PHONY: all debug clean

all: $(OUTPUT_FILE)
debug: $(OUTPUT_FILE)

clean:
rm -rf $(OUTPUT_FILE)

%.so: %.c
$(CC) $(CFLAGS) $(LDFLAGS) $(LIBFLAGS) $< -o $@

%.c: ptracer.h
113 changes: 113 additions & 0 deletions examples/connected-components/component.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright (c) 2024, The Pallene Developers
* Pallene Tracer is licensed under the MIT license.
* Please refer to the LICENSE and AUTHORS files for details
* SPDX-License-Identifier: MIT
*/

#include <stdlib.h>

#define PT_IMPLEMENTATION
#include "ptracer.h"

/* ---------------- PALLENE TRACER LUA INERFACE ---------------- */
#define CON_LUA_FRAMEENTER(fnptr) \
PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \
lua_upvalueindex(1), _frame)
/* ---------------- PALLENE TRACER LUA INERFACE END ---------------- */

/* ---------------- PALLENE TRACER C INTERFACE ---------------- */

#define CON_C_FRAMEENTER() \
PALLENE_TRACER_GENERIC_C_FRAMEENTER(fnstack, _frame)

#define CON_C_SETLINE() \
PALLENE_TRACER_GENERIC_C_SETLINE(fnstack)

#define CON_C_FRAMEEXIT() \
PALLENE_TRACER_FRAMEEXIT(fnstack)

/* ---------------- PALLENE TRACER C INTERFACE END ---------------- */

/* This is one way to work with Pallene Tracer call-stack, but certainly not recommended because
this way you loose the flexibility of using multiple Lua states. */
pt_fnstack_t *fnstack;

static void internal_dfs(lua_State *L, int *visited, int node) {
CON_C_FRAMEENTER();

if(visited[node]) {
CON_C_FRAMEEXIT();
return;
}

visited[node] = 1;

lua_rawgeti(L, 1, node); /* get the connected adjacent nodes of current node */
CON_C_SETLINE();
int n = luaL_len(L, -1); /* this line may trigger error */
lua_pop(L, 1);

/* for all the adjacent nodes */
for(int i = 1; i <= n; i++) {
lua_rawgeti(L, 1, node);
lua_rawgeti(L, -1, i);
int adjacent_node = lua_tointeger(L, -1);
lua_pop(L, 2); /* avoid Lua value-stack overflow by not keeping values on the stack. */

CON_C_SETLINE();
internal_dfs(L, visited, adjacent_node);
}

CON_C_FRAMEEXIT();
}

static int find_connected_components(lua_State *L, int *visited, int n) {
CON_C_FRAMEENTER();

int result = 0;

for(int i = 1; i <= n; i++) {
if(!visited[i]) {
result++;
CON_C_SETLINE();
internal_dfs(L, visited, i);
}
}

CON_C_FRAMEEXIT();
return result;
}

static int find_connected_components_lua(lua_State *L) {
CON_LUA_FRAMEENTER(find_connected_components_lua);

if(!lua_istable(L, 1))
luaL_error(L, "expected the first argument to be table");
if(!lua_isinteger(L, 2))
luaL_error(L, "expected the second argument to be integer");

int nodes = lua_tointeger(L, 2); /* get total number of nodes */
int *visited = calloc(nodes + 1, sizeof(int)); /* Lua prefers 1 based indexing */

/* Dispatch and push the result. */
lua_pushinteger(L, find_connected_components(L, visited, nodes));

free(visited);
return 1;
}

int luaopen_component(lua_State *L) {
fnstack = pallene_tracer_init(L);

lua_newtable(L);
int table = lua_gettop(L);

/* ---- find_connected_components ---- */
/* `pallene_tracer_init` function pushes the frameexit finalizer to the stack. */
lua_pushvalue(L, -2); /* passing the finalizer object as upvalue is generally the way to go. */
lua_pushcclosure(L, find_connected_components_lua, 1);
lua_setfield(L, table, "find_connected_components");

return 1;
}
20 changes: 20 additions & 0 deletions examples/connected-components/main.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
local component = require "component"

local nodes = 12
local graph = {
{ 2 }, -- 1st node
{ 1, 5 }, -- 2nd node
{ 5 }, -- 3rd node
{ 5 },
{ 2, 3, 4 },
{ 7, 8 },
{ 6 },
{ 6 },
{ 10, 12 },
{ 9, 11, 12 },
{ 10, 12 },
{ 9, 10, 11 } -- 12th node
};

local total_connected_components = component.find_connected_components(graph, nodes);
print(total_connected_components) -- expect: 3
27 changes: 27 additions & 0 deletions examples/fibonacci/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright (c) 2024, The Pallene Developers
# Pallene Tracer is licensed under the MIT license.
# Please refer to the LICENSE and AUTHORS files for details
# SPDX-License-Identifier: MIT

OUTPUT_FILE = fibonacci.so

CC = cc
CFLAGS = -O2 -std=c99 -pedantic -Wall -Wextra -Wformat-security
LIBFLAGS = -fPIC -shared

ifneq ($(findstring debug, $(MAKECMDGOALS)), )
CFLAGS += -DPT_DEBUG
endif

.PHONY: all debug clean

all: $(OUTPUT_FILE)
debug: $(OUTPUT_FILE)

clean:
rm -rf $(OUTPUT_FILE)

%.so: %.c
$(CC) $(CFLAGS) $(LDFLAGS) $(LIBFLAGS) $< -o $@

%.c: ptracer.h
6 changes: 3 additions & 3 deletions examples/fibonacci/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
-- Please refer to the LICENSE and AUTHORS files for details
-- SPDX-License-Identifier: MIT

local N = tonumber(arg[1]) or 40

local fibonacci = require "fibonacci"
print(fibonacci.fib(40))
-- Uncomment this and trigger an error. You can debug using the 'pallene-debug' script.
-- print(fibonacci.fib(40.0))
print(fibonacci.fib(N))
2 changes: 1 addition & 1 deletion run-tests
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
# ./run-tests
# ./run-tests -k
# ./run-tests spec/traceback_spec.lua
make tests && busted --verbose --no-keep-going "$@"
busted --verbose --no-keep-going "$@"
33 changes: 33 additions & 0 deletions spec/examples_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-- Copyright (c) 2024, The Pallene Developers
-- Pallene Tracer is licensed under the MIT license.
-- Please refer to the LICENSE and AUTHORS files for details
-- SPDX-License-Identifier: MIT

local util = require "spec.util"

local function assert_example(example, expected_content)
local cdir = util.shell_quote("examples/"..example)
local ok, err, output_content, _ =
util.outputs_of_execute(string.format("cd %s && make --quiet&& ../../pt-lua main.lua", cdir))
assert(ok, err)
assert.are.same(expected_content, output_content)

-- With Pallene Tracer tracebacks enabled
local ok, err, output_content, _ =
util.outputs_of_execute(string.format([[
cd %s
make clean --quiet
make debug --quiet
../../pt-lua main.lua
]], cdir))
assert(ok, err)
assert.are.same(expected_content, output_content)
end

it("Fibonacci", function()
assert_example("fibonacci", "102334155\n")
end)

it("Find Connected Components", function()
assert_example("connected-components", "3\n")
end)
4 changes: 2 additions & 2 deletions spec/tracebacks_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

local util = require "spec.util"

local function assert_test(example, expected_content)
local function assert_test(test, expected_content)
assert(util.execute("make --quiet tests"))

local dir = util.shell_quote("spec/tracebacks/"..example)
local dir = util.shell_quote("spec/tracebacks/"..test)
local ok, _, output_content, err_content =
util.outputs_of_execute("./pt-lua "..dir.."/main.lua")
assert(not ok, output_content)
Expand Down

0 comments on commit 58da3ab

Please sign in to comment.