[Snek] [PATCH v2] Add a skeleton for Lego EV3 port

Mikhail Gusarov dottedmag at dottedmag.net
Thu Feb 20 12:40:04 PST 2020


Signed-off-by: Mikhail Gusarov <dottedmag at dottedmag.net>
---
 ports/ev3/.clang-format    |  78 ++++++++++++++++++++++++
 ports/ev3/.dir-locals.el   |   2 +
 ports/ev3/.gitignore       |   1 +
 ports/ev3/Makefile         |  54 +++++++++++++++++
 ports/ev3/snek-ev3.builtin |  21 +++++++
 ports/ev3/snek-ev3.h       |  45 ++++++++++++++
 ports/ev3/snek-main.c      | 120 +++++++++++++++++++++++++++++++++++++
 snek-install.defs          |   1 +
 8 files changed, 322 insertions(+)
 create mode 100644 ports/ev3/.clang-format
 create mode 100644 ports/ev3/.dir-locals.el
 create mode 100644 ports/ev3/.gitignore
 create mode 100644 ports/ev3/Makefile
 create mode 100644 ports/ev3/snek-ev3.builtin
 create mode 100644 ports/ev3/snek-ev3.h
 create mode 100644 ports/ev3/snek-main.c

diff --git a/ports/ev3/.clang-format b/ports/ev3/.clang-format
new file mode 100644
index 0000000..e4e0ccf
--- /dev/null
+++ b/ports/ev3/.clang-format
@@ -0,0 +1,78 @@
+---
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: true
+AlignEscapedNewlines: Left
+AlignOperands: true
+AlignTrailingComments: false
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: All
+AlwaysBreakAfterReturnType: All
+AlwaysBreakBeforeMultilineStrings: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+  AfterClass: false
+  AfterControlStatement: false
+  AfterEnum: false
+  AfterFunction: true
+  AfterStruct: false
+  AfterUnion: false
+  AfterExternBlock: false
+  BeforeCatch: false
+  BeforeElse: false
+  IndentBraces: false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeInheritanceComma: false
+BreakBeforeTernaryOperators: false
+BreakStringLiterals: false
+ColumnLimit: 120
+CommentPragmas: '^ IWYU pragma:'
+ContinuationIndentWidth: 8
+DerivePointerAlignment: false
+ExperimentalAutoDetectBinPacking: false
+IncludeBlocks: Preserve
+IncludeCategories:
+  - Regex: '.*'
+    Priority: 1
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: false
+IndentPPDirectives: None
+IndentWidth: 8
+IndentWrappedFunctionNames: false
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+
+PenaltyBreakAssignment: 10
+PenaltyBreakBeforeFirstCallParameter: 30
+PenaltyBreakComment: 10
+PenaltyBreakFirstLessLess: 0
+PenaltyBreakString: 10
+PenaltyExcessCharacter: 100
+PenaltyReturnTypeOnItsOwnLine: 60
+
+PointerAlignment: Right
+ReflowComments: false
+SortIncludes: false
+SortUsingDeclarations: false
+SpaceAfterCStyleCast: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+TabWidth: 8
+UseTab: Always
+...
diff --git a/ports/ev3/.dir-locals.el b/ports/ev3/.dir-locals.el
new file mode 100644
index 0000000..040cf68
--- /dev/null
+++ b/ports/ev3/.dir-locals.el
@@ -0,0 +1,2 @@
+((c-mode . ((flycheck-clang-include-path . ("../.."))
+            (flycheck-clang-definitions . ("SNEK_VERSION=\"\"")))))
diff --git a/ports/ev3/.gitignore b/ports/ev3/.gitignore
new file mode 100644
index 0000000..ea3551e
--- /dev/null
+++ b/ports/ev3/.gitignore
@@ -0,0 +1 @@
+snek-ev3-*
diff --git a/ports/ev3/Makefile b/ports/ev3/Makefile
new file mode 100644
index 0000000..36a6cd9
--- /dev/null
+++ b/ports/ev3/Makefile
@@ -0,0 +1,54 @@
+#
+# Copyright © 2020 Mikhail Gusarov <dottedmag at dottedmag.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+
+SNEK_ROOT=../..
+
+CC=arm-linux-gnueabi-gcc
+PROGNAME=snek-ev3
+PROG=$(PROGNAME)-$(SNEK_VERSION)
+
+SNEK_LOCAL_SRC = \
+	snek-main.c \
+	../posix/snek-posix.c \
+	snek-math.c \
+	snek-input.c
+
+SNEK_LOCAL_INC = snek-ev3.h
+SNEK_LOCAL_CFLAGS = -DSNEK_USE_GLIBC_2_4_MATH
+SNEK_LOCAL_BUILTINS = \
+	snek-ev3.builtin \
+	$(SNEK_ROOT)/snek-math.builtin \
+	$(SNEK_ROOT)/snek-input.builtin
+
+include $(SNEK_ROOT)/snek-install.defs
+
+SNEK_CFLAGS = $(SNEK_MOST_WARNINGS) $(SNEK_BASE_CFLAGS)
+
+OPT?=-O3
+
+CFLAGS+=-DSNEK_MEM_INCLUDE_NAME $(OPT) -g -I. $(SNEK_CFLAGS) -Werror $(CPPFLAGS)
+
+LIBS=-lm
+
+all: $(PROG)
+
+$(PROG): $(SNEK_OBJ)
+	$(call quiet,CC) $(CFLAGS) $(LDFLAGS) -o $@ $(SNEK_OBJ) $(LIBS)
+
+install: $(PROG)
+	install -d $(DESTDIR)$(SHAREDIR)
+	install $(PROG) $(DESTDIR)$(SHAREDIR)
+
+clean::
+	rm -f $(PROG)
diff --git a/ports/ev3/snek-ev3.builtin b/ports/ev3/snek-ev3.builtin
new file mode 100644
index 0000000..494f215
--- /dev/null
+++ b/ports/ev3/snek-ev3.builtin
@@ -0,0 +1,21 @@
+#
+# Copyright © 2020 Mikhail Gusarov <dottedmag at dottedmag.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+exit, 1
+time.sleep, 1
+time.monotonic, 0
+random.seed, 1
+random.randrange, 1
+
+#include "snek-ev3.h"
+#define SNEK_POOL 262144
diff --git a/ports/ev3/snek-ev3.h b/ports/ev3/snek-ev3.h
new file mode 100644
index 0000000..d004da6
--- /dev/null
+++ b/ports/ev3/snek-ev3.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2020 Mikhail Gusarov <dottedmag at dottedmag.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+#ifndef _SNEK_EV3_H_
+#define _SNEK_EV3_H_
+
+/*
+ * Stable ev3dev version is based on Debian stretch, with glibc 2.24.
+ *
+ * glibc 2.27 has changed[1] the version of several libm symbols due to an
+ * optimization, so binaries linked against glibc >= 2.27 (e.g. in Debian buster
+ * and later) fail to load on ev3dev with
+ *
+ *   /lib/arm-linux-gnueabi/libm.so.6:
+ *   version `GLIBC_2.27' not found (required by ./snek-ev3-1.3)
+ *
+ * Force using older versions of these symbols to allow linking against newer
+ * glibc and hence simplify build setup.
+ *
+ * [1] https://sourceware.org/ml/libc-announce/2018/msg00000.html
+ */
+#if defined(SNEK_USE_GLIBC_2_4_MATH)
+__asm__(".symver expf,expf at GLIBC_2.4");
+__asm__(".symver exp2f,exp2f at GLIBC_2.4");
+__asm__(".symver logf,logf at GLIBC_2.4");
+__asm__(".symver log2f,log2f at GLIBC_2.4");
+__asm__(".symver powf,powf at GLIBC_2.4");
+#endif
+
+int
+snek_getc(void);
+
+#define SNEK_GETC() snek_getc()
+
+#endif /* _SNEK_EV3_H_ */
diff --git a/ports/ev3/snek-main.c b/ports/ev3/snek-main.c
new file mode 100644
index 0000000..d4b6c63
--- /dev/null
+++ b/ports/ev3/snek-main.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2018 Keith Packard <keithp at keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include "snek.h"
+#include <getopt.h>
+
+static FILE *snek_posix_input;
+
+static const struct option options[] = {
+	{.name = "version", .has_arg = 0, .val = 'v'},
+	{.name = "file", .has_arg = 1, .val = 'f'},
+	{.name = "help", .has_arg = 0, .val = '?'},
+	{.name = NULL, .has_arg = 0, .val = 0},
+};
+
+static void
+usage(char *program, int val)
+{
+	fprintf(stderr, "usage: %s [--version] [--help] [--file <file.py>] <program.py>\n", program);
+	exit(val);
+}
+
+static int
+snek_getc_interactive(void)
+{
+	static char  line_base[4096];
+	static char *line;
+	int	     c;
+
+	if (!line) {
+		char *prompt = "> ";
+		if (snek_parse_middle)
+			prompt = "+ ";
+		puts(prompt);
+		line = fgets(line_base, 4096, stdin);
+		if (!line)
+			return EOF;
+	}
+	c = (*line++) & 0xff;
+	if (!c) {
+		c = '\n';
+		line = 0;
+	}
+	return c;
+}
+
+int
+snek_getc(void)
+{
+	if (snek_interactive)
+		return snek_getc_interactive();
+	return getc(snek_posix_input);
+}
+
+int
+main(int argc, char **argv)
+{
+	int   c;
+	char *file = NULL;
+
+	while ((c = getopt_long(argc, argv, "v?f:", options, NULL)) != -1) {
+		switch (c) {
+		case 'v':
+			printf("%s version %s\n", argv[0], SNEK_VERSION);
+			exit(0);
+			break;
+		case 'f':
+			file = optarg;
+			break;
+		case '?':
+			usage(argv[0], 0);
+			break;
+		default:
+			usage(argv[0], 1);
+			break;
+		}
+	}
+
+	snek_init();
+
+	if (file) {
+		snek_file = file;
+		snek_posix_input = fopen(snek_file, "r");
+		if (!snek_posix_input) {
+			perror(snek_file);
+			exit(1);
+		}
+		snek_parse();
+	}
+
+	if (argv[optind]) {
+		snek_file = argv[optind];
+		snek_posix_input = fopen(snek_file, "r");
+		if (!snek_posix_input) {
+			perror(snek_file);
+			exit(1);
+		}
+	} else {
+		snek_file = "<stdin>";
+		snek_posix_input = stdin;
+		snek_interactive = true;
+		printf("Welcome to Snek version %s\n", SNEK_VERSION);
+	}
+
+	bool ret = snek_parse() == snek_parse_success;
+	if (snek_posix_input == stdin)
+		printf("\n");
+	return ret ? 0 : 1;
+}
diff --git a/snek-install.defs b/snek-install.defs
index a032dd2..6f1e57b 100644
--- a/snek-install.defs
+++ b/snek-install.defs
@@ -36,6 +36,7 @@ FIRMWARE ?= \
 	$(SNEK_PORTS)/qemu-riscv/snek-qemu-riscv-$(SNEK_VERSION).elf \
 	$(SNEK_PORTS)/snekboard/snek-board-$(SNEK_VERSION).uf2 \
 	$(SNEK_PORTS)/uduino/snek-uduino-$(SNEK_VERSION).hex \
+	$(SNEK_PORTS)/ev3/snek-ev3-$(SNEK_VERSION) \
 	$(SNEK_PORTS_HIFIVE1REVB) $(SNEK_PORTS_ESP32)
 
 USBFIRMWARE ?= \
-- 
2.24.0



More information about the Snek mailing list