aboutsummaryrefslogtreecommitdiff
path: root/works/life
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-11-24 20:43:52 +0800
committercrupest <crupest@outlook.com>2021-11-24 20:43:52 +0800
commit1ea48b1fcb7ac64935018b1ced2d0f11982872ea (patch)
tree42c69714653addebbdb1cf0122e2ebda918dbc16 /works/life
parent224d5fec9b9377faa4bf8d3da0e37f675ef5ea03 (diff)
downloadcrupest-1ea48b1fcb7ac64935018b1ced2d0f11982872ea.tar.gz
crupest-1ea48b1fcb7ac64935018b1ced2d0f11982872ea.tar.bz2
crupest-1ea48b1fcb7ac64935018b1ced2d0f11982872ea.zip
import(life): Add compile principle experiment 3.
Diffstat (limited to 'works/life')
-rw-r--r--works/life/compile-principle-experiment/3/lex.l17
-rw-r--r--works/life/compile-principle-experiment/3/main.c107
-rw-r--r--works/life/compile-principle-experiment/3/main.h25
-rw-r--r--works/life/compile-principle-experiment/3/makefile22
-rw-r--r--works/life/compile-principle-experiment/3/syn.y42
-rw-r--r--works/life/main.cpp36
-rw-r--r--works/life/test.ipynb49
7 files changed, 262 insertions, 36 deletions
diff --git a/works/life/compile-principle-experiment/3/lex.l b/works/life/compile-principle-experiment/3/lex.l
new file mode 100644
index 0000000..ddea92d
--- /dev/null
+++ b/works/life/compile-principle-experiment/3/lex.l
@@ -0,0 +1,17 @@
+%{
+#include "main.h"
+#include "syn.h"
+%}
+%option noyywrap
+%%
+[ \t] { ; } /* skip blanks and tabs */
+[0-9]+\.?|[0-9]*\.[0-9]+ {
+ sscanf(yytext, "%lf", &yylval.val); return NUMBER; }
+[a-zA-Z][a-zA-Z0-9]* {
+ Symbol *s;
+ if ((s=cru_symbol_lookup(yytext)) == 0)
+ s = cru_symbol_install(yytext, UNDEF, (SymbolValue)0.0);
+ yylval.sym = s;
+ return s->type == UNDEF ? VAR : s->type; }
+\n { lineno++; return '\n'; } /* everything else */
+. { return yytext[0]; }
diff --git a/works/life/compile-principle-experiment/3/main.c b/works/life/compile-principle-experiment/3/main.c
new file mode 100644
index 0000000..7cd8c28
--- /dev/null
+++ b/works/life/compile-principle-experiment/3/main.c
@@ -0,0 +1,107 @@
+#include "main.h"
+
+#include "syn.h"
+
+#include <errno.h>
+#include <math.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static Symbol *symlist = 0; /* symbol table: linked list */
+
+void *emalloc(size_t n) /* check return from malloc */
+{
+ void *p = malloc(n);
+ if (p == 0)
+ execerror("out of memory", (char *)0);
+ return p;
+}
+
+Symbol *cru_symbol_lookup(const char *name) {
+ for (Symbol *sp = symlist; sp != NULL; sp = sp->next)
+ if (strcmp(sp->name, name) == 0)
+ return sp;
+ return NULL;
+}
+
+Symbol *cru_symbol_install(const char *name, int type, SymbolValue value) {
+ Symbol *sp = (Symbol *)emalloc(sizeof(Symbol));
+ sp->name = emalloc(strlen(name) + 1);
+ strcpy(sp->name, name);
+ sp->type = type;
+ sp->value = value;
+ sp->next = symlist;
+ symlist = sp;
+ return sp;
+}
+
+jmp_buf begin;
+int lineno;
+
+void warning(const char *s, const char *t) {
+ fprintf(stderr, "%s", s);
+ if (t)
+ fprintf(stderr, " %s", t);
+ fprintf(stderr, " near line %d\n", lineno);
+}
+
+void yyerror(const char *s) { warning(s, NULL); }
+
+void execerror(const char *s, const char *t) {
+ warning(s, t);
+ longjmp(begin, 0);
+}
+
+double errcheck(double result, const char *name) {
+ if (errno == EDOM) {
+ errno = 0;
+ execerror(name, "argument out of domain");
+ } else if (errno == ERANGE) {
+ errno = 0;
+ execerror(name, "result out of range");
+ }
+ return result;
+}
+
+double Log(double x) { return errcheck(log(x), "log"); }
+double Log10(double x) { return errcheck(log10(x), "log10"); }
+double Sqrt(double x) { return errcheck(sqrt(x), "sqrt"); }
+double Exp(double x) { return errcheck(exp(x), "exp"); }
+double Pow(double x, double y) { return errcheck(pow(x, y), "exponentiation"); }
+double integer(double x) { return (double)(long)x; }
+
+static struct { /* Constants */
+ char *name;
+ double cval;
+} consts[] = {
+ {"PI", 3.14159265358979323846}, {"E", 2.71828182845904523536},
+ {"GAMMA", 0.57721566490153286060}, {"DEG", 57.29577951308232087680},
+ {"PHI", 1.61803398874989484820},
+};
+
+static struct { /* Built-ins */
+ char *name;
+ double (*func)();
+} builtins[] = {
+ {"sin", sin}, {"cos", cos}, {"atan", atan},
+ {"log", Log}, {"log10", Log10}, {"exp", Exp},
+ {"sqrt", Sqrt}, {"int", integer}, {"abs", fabs},
+};
+
+void init() {
+ for (int i = 0; i < sizeof(consts) / sizeof(*consts); i++)
+ cru_symbol_install(consts[i].name, VAR, (SymbolValue)consts[i].cval);
+ for (int i = 0; i < sizeof(builtins) / sizeof(*builtins); i++) {
+ cru_symbol_install(builtins[i].name, BLTIN, (SymbolValue)builtins->func);
+ }
+}
+
+int main(int argc, char **argv) {
+ init();
+ (void)setjmp(begin);
+ yyparse();
+
+ return 0;
+}
diff --git a/works/life/compile-principle-experiment/3/main.h b/works/life/compile-principle-experiment/3/main.h
new file mode 100644
index 0000000..9bd6e56
--- /dev/null
+++ b/works/life/compile-principle-experiment/3/main.h
@@ -0,0 +1,25 @@
+#pragma once
+
+typedef union SymbolValue {
+ double val;
+ double (*ptr)();
+} SymbolValue;
+
+typedef struct Symbol {
+ char *name;
+ int type;
+ SymbolValue value;
+ struct Symbol *next;
+} Symbol;
+
+Symbol *cru_symbol_lookup(const char *name);
+Symbol *cru_symbol_install(const char *name, int type, SymbolValue value);
+
+double Pow(double x, double y);
+
+int yylex();
+int yyparse();
+void yyerror(const char *s);
+
+extern int lineno;
+void execerror(const char *s, const char *t);
diff --git a/works/life/compile-principle-experiment/3/makefile b/works/life/compile-principle-experiment/3/makefile
new file mode 100644
index 0000000..cf6333c
--- /dev/null
+++ b/works/life/compile-principle-experiment/3/makefile
@@ -0,0 +1,22 @@
+main: main.o lex.o syn.o
+ cc lex.o syn.o main.o -o main
+
+main.o: main.c main.h syn.h
+ cc -c -o main.o main.c
+
+lex.c: lex.l
+ flex -o lex.c lex.l
+
+lex.o: lex.c syn.h main.h
+ cc -c -o lex.o lex.c
+
+syn.c syn.h: syn.y
+ bison syn.y -d -o syn.c
+
+syn.o: syn.c syn.h main.h
+ cc -c -o syn.o syn.c
+
+PHONY: clean
+
+clean:
+ rm -f *.o lex.c syn.c syn.h main
diff --git a/works/life/compile-principle-experiment/3/syn.y b/works/life/compile-principle-experiment/3/syn.y
new file mode 100644
index 0000000..80abb17
--- /dev/null
+++ b/works/life/compile-principle-experiment/3/syn.y
@@ -0,0 +1,42 @@
+%{
+#include "main.h"
+#include <stdio.h>
+%}
+%union {
+ double val; /* actual value */
+ Symbol *sym; /* symbol table pointer */
+}
+%token <val> NUMBER
+%token <sym> VAR BLTIN UNDEF
+%type <val> expr asgn
+%right '='
+%left '+' '-'
+%left '*' '/'
+%left UNARYMINUS
+%right '^' /* exponentiation */
+%%
+list: /* nothing */
+ | list '\n'
+ | list asgn '\n'
+ | list expr '\n' { printf("\t%.8g\n", $2); }
+ | list error '\n' { yyerrok; }
+ ;
+asgn: VAR '=' expr { $$=$1->value.val=$3; $1->type = VAR; }
+ ;
+expr: NUMBER
+ | VAR { if ($1->type == UNDEF)
+ execerror("undefined variable", $1->name);
+ $$ = $1->value.val; }
+ | BLTIN '(' expr ')' { $$ = (*($1->value.ptr))($3); }
+ | expr '+' expr { $$ = $1 + $3; }
+ | expr '-' expr { $$ = $1 - $3; }
+ | expr '*' expr { $$ = $1 * $3; }
+ | expr '/' expr {
+ if ($3 == 0.0)
+ execerror("division by zero", "");
+ $$ = $1 / $3; }
+ | expr '^' expr { $$ = Pow($1, $3); }
+ | '(' expr ')' { $$ = $2; }
+ | '-' expr %prec UNARYMINUS { $$ = -$2; }
+ ;
+%%
diff --git a/works/life/main.cpp b/works/life/main.cpp
deleted file mode 100644
index efb5bff..0000000
--- a/works/life/main.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <WinSock2.h>
-#include <Windows.h>
-#include <cassert>
-#include <iostream>
-#include <iphlpapi.h>
-#include <string>
-
-std::wstring ToString(const SOCKET_ADDRESS &addr) {
- DWORD buffer_length = 100;
- wchar_t buffer[100];
- auto error = WSAAddressToStringW(addr.lpSockaddr, addr.iSockaddrLength, NULL,
- buffer, &buffer_length);
- assert(error == 0);
- return std::wstring(buffer);
-}
-
-int main() {
- WSADATA wsaData;
- int error = WSAStartup(MAKEWORD(2, 0), &wsaData);
- assert(error == 0);
-
- ULONG buffer_size = 100000;
- PIP_ADAPTER_ADDRESSES_LH buffer =
- (PIP_ADAPTER_ADDRESSES_LH)malloc(buffer_size);
- ULONG error2 = GetAdaptersAddresses(
- AF_INET,
- GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS |
- GAA_FLAG_INCLUDE_ALL_INTERFACES | GAA_FLAG_SKIP_MULTICAST,
- NULL, buffer, &buffer_size);
- assert(error2 == ERROR_SUCCESS);
-
- std::wcout << ToString(buffer->FirstPrefix->Address) << L"\n";
- std::wcout << buffer->FirstGatewayAddress << L"\n";
-
- return 0;
-}
diff --git a/works/life/test.ipynb b/works/life/test.ipynb
new file mode 100644
index 0000000..7536d4b
--- /dev/null
+++ b/works/life/test.ipynb
@@ -0,0 +1,49 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "tensor(6)\n"
+ ]
+ }
+ ],
+ "source": [
+ "import torch\n",
+ "\n",
+ "t = torch.tensor([1, 2, 3]);\n",
+ "print(t.sum())\n"
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.9.9 64-bit",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.9"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}