aboutsummaryrefslogtreecommitdiff
path: root/sem3/osc
diff options
context:
space:
mode:
Diffstat (limited to 'sem3/osc')
-rw-r--r--sem3/osc/miniproject/cnasm/Makefile30
-rw-r--r--sem3/osc/miniproject/cnasm/ast.c98
-rw-r--r--sem3/osc/miniproject/cnasm/ast.h53
-rw-r--r--sem3/osc/miniproject/cnasm/codegen.c132
-rw-r--r--sem3/osc/miniproject/cnasm/codegen.h14
-rw-r--r--sem3/osc/miniproject/cnasm/regn.l39
-rw-r--r--sem3/osc/miniproject/cnasm/regn.y81
-rw-r--r--sem3/osc/miniproject/cnasm/test.asm39
-rw-r--r--sem3/osc/mm1/.gitignore10
-rw-r--r--sem3/osc/mm1/mm1/Makefile7
-rw-r--r--sem3/osc/mm1/mm1/Readme.md34
-rw-r--r--sem3/osc/mm1/mm1/jmod.c70
-rw-r--r--sem3/osc/mm1/mm2/tprog.c71
-rw-r--r--sem3/osc/mm10/Makefile25
-rw-r--r--sem3/osc/mm10/opg1.l22
-rw-r--r--sem3/osc/mm10/opg3.l36
-rw-r--r--sem3/osc/mm10/opg4.l101
-rw-r--r--sem3/osc/mm10/opgaver.md55
-rw-r--r--sem3/osc/mm10/stateMachine.pngbin0 -> 21881 bytes
-rw-r--r--sem3/osc/mm11/opgaver.md32
-rw-r--r--sem3/osc/mm11/regn/Makefile30
-rw-r--r--sem3/osc/mm11/regn/regn.l40
-rw-r--r--sem3/osc/mm11/regn/regn.y54
-rw-r--r--sem3/osc/mm11/regn/symtab.c50
-rw-r--r--sem3/osc/mm11/regn/symtab.h20
-rw-r--r--sem3/osc/mm11/regn2/Makefile30
-rw-r--r--sem3/osc/mm11/regn2/regn.l27
-rw-r--r--sem3/osc/mm11/regn2/regn.y46
-rw-r--r--sem3/osc/mm3/opgaver.md47
-rw-r--r--sem3/osc/mm8/mm8.ino47
-rw-r--r--sem3/osc/mm9/opgaver.md129
-rw-r--r--sem3/osc/noter.md17
32 files changed, 1486 insertions, 0 deletions
diff --git a/sem3/osc/miniproject/cnasm/Makefile b/sem3/osc/miniproject/cnasm/Makefile
new file mode 100644
index 0000000..9ace547
--- /dev/null
+++ b/sem3/osc/miniproject/cnasm/Makefile
@@ -0,0 +1,30 @@
+
+LEX=flex
+YACC=bison
+LIBS=-ly -lfl -lm
+CC=gcc
+
+PROG=regn
+TRASH=lex.yy.c $(PROG).tab.c $(PROG) $(PROG).tab.h $(PROG).output
+
+$(PROG): $(PROG).tab.o lex.yy.o ast.c codegen.c
+ $(CC) -ggdb -o $@ $^ $(LIBS)
+
+$(PROG).tab.c $(PROG).tab.h: $(PROG).y
+ $(YACC) -d -v $(PROG).y
+
+lex.yy.c: $(PROG).l
+ $(LEX) $(PROG).l
+
+%.o: %.c
+ $(CC) -ggdb -c -o $@ $^
+
+PHONY: clean run
+
+run: $(PROG)
+ ./$(PROG)
+
+clean:
+ rm -f *.o
+ rm -f $(TRASH)
+
diff --git a/sem3/osc/miniproject/cnasm/ast.c b/sem3/osc/miniproject/cnasm/ast.c
new file mode 100644
index 0000000..035b75d
--- /dev/null
+++ b/sem3/osc/miniproject/cnasm/ast.c
@@ -0,0 +1,98 @@
+#include "ast.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+static ast_node_t *create_empty_node() {
+ ast_node_t *n = malloc(sizeof(ast_node_t));
+ memset(n, 0, sizeof(ast_node_t));
+}
+
+ast_node_t *insert_ctrl(enum ntype t, cond_t *c, ast_node_t *iftrue, ast_node_t *iffalse) {
+ ast_node_t *n = create_empty_node();
+
+ n->t = t;
+ n->flowctrl.condition = c;
+ n->flowctrl.iftrue = iftrue;
+ n->flowctrl.iffalse = iffalse;
+
+ return n;
+}
+
+ast_node_t *insert_for(char *pre, cond_t *c, char *inc, ast_node_t *stuff) {
+ ast_node_t *n = create_empty_node();
+
+ n->t = TFOR;
+ n->forloop.condition = c;
+ n->forloop.pre = pre;
+ n->forloop.inc = inc;
+ n->forloop.stuff = stuff;
+
+ return n;
+}
+
+ast_node_t *insert_stm(ast_node_t *stm, ast_node_t *stm_list) {
+ ast_node_t *n = create_empty_node();
+
+ n->t = TSTM_LIST;
+ n->list.children[0] = stm_list;
+ n->list.children[1] = stm;
+
+ return n;
+}
+ast_node_t *insert_ident(char *ident) {
+ ast_node_t *n = create_empty_node();
+
+ n->t = TIDENT;
+ n->ident = ident;
+
+ return n;
+}
+
+cond_t *insert_cond(uint8_t cmp, char *a, char *b) {
+ cond_t *c = malloc( sizeof(cond_t));
+
+ c->cmp = cmp;
+ c->a = a;
+ c->b = b;
+}
+
+void node_print(ast_node_t *node) {
+ if( !node ){
+ printf("Nil");
+ return;
+ }
+ switch(node->t) {
+ case TSTM_LIST:
+ printf("Stm_list(");
+ node_print(node->list.children[0]);
+ printf(",");
+ node_print(node->list.children[1]);
+ printf(")");
+ break;
+ case TIF:
+ printf("If");
+ printf("(%s %c %s) {", node->flowctrl.condition->a,
+ node->flowctrl.condition->cmp,
+ node->flowctrl.condition->b);
+ node_print(node->flowctrl.iftrue);
+ printf("}{");
+ node_print(node->flowctrl.iffalse);
+ printf("}");
+ break;
+ case TIDENT:
+ printf("%s", node->ident);
+ break;
+ case TWHILE:
+ printf("while");
+ printf("(%s %c %s) {", node->flowctrl.condition->a,
+ node->flowctrl.condition->cmp,
+ node->flowctrl.condition->b);
+ node_print(node->flowctrl.iftrue);
+ printf("}");
+ break;
+ default:
+ printf("invalid");
+ }
+}
diff --git a/sem3/osc/miniproject/cnasm/ast.h b/sem3/osc/miniproject/cnasm/ast.h
new file mode 100644
index 0000000..61a8f4f
--- /dev/null
+++ b/sem3/osc/miniproject/cnasm/ast.h
@@ -0,0 +1,53 @@
+#ifndef AST_HEADER
+#define AST_HEADER
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#define CEQ 0x10
+#define CNEQ CEQ ^ 0x80
+#define CGT 0x20
+#define CLT 0x30
+#define CLEQ CGT ^ 0x80
+#define CGEQ CLT ^ 0x80
+
+enum ntype { TSTM_LIST, TIF, TFOR, TIDENT, TWHILE};
+
+typedef struct cond {
+ uint8_t cmp;
+ char *a;
+ char *b;
+} cond_t;
+
+typedef struct ast_node {
+ enum ntype t;
+ // Dependent on type
+ union {
+ struct {
+ cond_t *condition;
+ struct ast_node *iftrue;
+ struct ast_node *iffalse;
+ } flowctrl;
+ struct {
+ cond_t *condition;
+ char *pre;
+ char *inc;
+ struct ast_node *stuff;
+ } forloop;
+ char *ident;
+ struct {
+ struct ast_node *children[2];
+ } list;
+ };
+} ast_node_t;
+
+ast_node_t *insert_ctrl(enum ntype t, cond_t *c, ast_node_t *iftrue, ast_node_t *iffalse);
+ast_node_t *insert_stm(ast_node_t *stm, ast_node_t *stm_list);
+ast_node_t *insert_ident(char *ident);
+ast_node_t *insert_for(char *pre, cond_t *c, char *inc, ast_node_t *stuff);
+
+cond_t *insert_cond(uint8_t cmp, char *a, char *b);
+
+void node_print(ast_node_t *node);
+
+#endif
diff --git a/sem3/osc/miniproject/cnasm/codegen.c b/sem3/osc/miniproject/cnasm/codegen.c
new file mode 100644
index 0000000..c995df9
--- /dev/null
+++ b/sem3/osc/miniproject/cnasm/codegen.c
@@ -0,0 +1,132 @@
+#include "codegen.h"
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include "ast.h"
+
+static void gencondjmp(FILE *f, cond_t *c, bool neg) {
+ uint8_t cmp = neg ? c->cmp^0x80 : c->cmp;
+ fprintf(f, "cmp %s %s\n", c->a, c->b);
+ switch(cmp) {
+ case CEQ:
+ fprintf(f, "je ");
+ break;
+ case CNEQ:
+ fprintf(f, "jne ");
+ break;
+ case CGT:
+ fprintf(f, "jg ");
+ break;
+ case CLT:
+ fprintf(f, "jl ");
+ break;
+ case CLEQ:
+ fprintf(f, "jle ");
+ break;
+ case CGEQ:
+ fprintf(f, "jge ");
+ break;
+ default:
+ fprintf(stderr, "Invalid cmp type %x", cmp);
+ fprintf(f, "jmp ");
+ }
+}
+
+static void genif(FILE *f, struct genctx *ctx, ast_node_t *n) {
+ bool doElse = n->flowctrl.iffalse;
+ // Create conditional jump
+ gencondjmp(f, n->flowctrl.condition, true);
+ if( doElse ) {
+ fprintf(f, "else_%d\n", ctx->nested);
+ } else {
+ fprintf(f, "end_%d\n", ctx->nested);
+ }
+
+ struct genctx octx = { ctx->nested+1 };
+ // Paste code
+ gentree(f, &octx, n->flowctrl.iftrue);
+
+ // Do else
+ if( doElse ) {
+ fprintf(f, "jmp end_%d\n", ctx->nested);
+ fprintf(f, "else_%d:\n", ctx->nested);
+ gentree(f, &octx, n->flowctrl.iffalse);
+ }
+
+ // End block
+ fprintf(f, "end_%d:\n", ctx->nested);
+}
+
+static void genwhile(FILE *f, struct genctx *ctx, ast_node_t *n) {
+ // Create loop label
+ fprintf(f, "loop_%d:\n", ctx->nested);
+
+ // Create conditional jump
+ gencondjmp(f, n->flowctrl.condition, true);
+ fprintf(f, "end_%d\n", ctx->nested);
+
+ struct genctx octx = { ctx->nested+1 };
+ // Paste code
+ gentree(f, &octx, n->flowctrl.iftrue);
+
+ // Jump to start
+ fprintf(f, "jmp loop_%d\n", ctx->nested);
+
+ // End block
+ fprintf(f, "end_%d:\n", ctx->nested);
+}
+
+static void genfor(FILE *f, struct genctx *ctx, ast_node_t *n) {
+ // Do pre stuff
+ fprintf(f, "%s\n", n->forloop.pre);
+
+ // Create loop label
+ fprintf(f, "loop_%d:\n", ctx->nested);
+
+ // Create conditional jump
+ gencondjmp(f, n->flowctrl.condition, true);
+ fprintf(f, "end_%d\n", ctx->nested);
+
+ struct genctx octx = { ctx->nested+1 };
+ // Paste code
+ gentree(f, &octx, n->forloop.stuff);
+
+ // Do inc stuff
+ fprintf(f, "%s\n", n->forloop.inc);
+ // Jump to start
+ fprintf(f, "jmp loop_%d\n", ctx->nested);
+
+ // End block
+ fprintf(f, "end_%d:\n", ctx->nested);
+}
+
+void gentree(FILE *f, struct genctx *ctx, ast_node_t *n) {
+ if( !n ) {
+ return;
+ }
+ if( ctx == NULL ) {
+ ctx = malloc(sizeof(struct genctx));
+ ctx->nested = 0;
+ }
+ switch(n->t) {
+ case TSTM_LIST:
+ gentree(f, ctx, n->list.children[0]);
+ gentree(f, ctx, n->list.children[1]);
+ break;
+ case TIF:
+ genif(f, ctx, n);
+ break;
+ case TIDENT:
+ fprintf(f, "%s\n", n->ident);
+ break;
+ case TFOR:
+ genfor(f, ctx, n);
+ break;
+ case TWHILE:
+ genwhile(f, ctx, n);
+ break;
+ default:
+ return;
+ }
+}
diff --git a/sem3/osc/miniproject/cnasm/codegen.h b/sem3/osc/miniproject/cnasm/codegen.h
new file mode 100644
index 0000000..24ad6c4
--- /dev/null
+++ b/sem3/osc/miniproject/cnasm/codegen.h
@@ -0,0 +1,14 @@
+
+#ifndef CODEGEN_HEADER
+#define CODEGEN_HEADER
+
+#include <stdio.h>
+#include "ast.h"
+
+struct genctx {
+ unsigned int nested;
+};
+
+void gentree(FILE *f, struct genctx *ctx, ast_node_t *n);
+
+#endif
diff --git a/sem3/osc/miniproject/cnasm/regn.l b/sem3/osc/miniproject/cnasm/regn.l
new file mode 100644
index 0000000..00876d6
--- /dev/null
+++ b/sem3/osc/miniproject/cnasm/regn.l
@@ -0,0 +1,39 @@
+%{
+#include <math.h>
+#include <string.h>
+#include "regn.tab.h"
+#include "ast.h"
+%}
+
+id [a-zA-Z0-9_;]([^\n=><(){}])*
+if if[ \t]*
+else else[ \t]*
+for for[ \t]*
+while while[ \t]*
+
+%%
+
+{if} {return IFF;};
+{else} {return EELSE;};
+{for} {return FFOR;};
+{while} {return WHILE;};
+"(" {return LP;};
+")" {return RP;};
+"{" {return LCP;};
+"}" {return RCP;};
+"<" {yylval.cmp = CLT; return CMP;};
+">" {yylval.cmp = CGT; return CMP;};
+"=" {yylval.cmp = CEQ; return CMP;};
+"!=" {yylval.cmp = CNEQ; return CMP;};
+{id} {yylval.string = strdup(yytext);return ID;};
+[1-9][0-9]* {yylval.string = yytext;return NO;};
+
+
+
+[ \t\n] ;
+
+. {return yytext[0];}
+
+%%
+
+// TODO match normal assembler
diff --git a/sem3/osc/miniproject/cnasm/regn.y b/sem3/osc/miniproject/cnasm/regn.y
new file mode 100644
index 0000000..b72d440
--- /dev/null
+++ b/sem3/osc/miniproject/cnasm/regn.y
@@ -0,0 +1,81 @@
+%{
+#include "ast.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include "codegen.h"
+
+#define CLEAN_BOTH 2
+#define CLEAN_DST 1
+
+char *strconcat(char *dst, char *src, unsigned int clean) {
+ size_t dstlen = strlen(dst) + 1;
+ size_t srclen = strlen(src) + 1;
+
+ // Create new duplicate
+ char *new = malloc(( dstlen + srclen ) * sizeof(char));
+
+ // Copy stuff
+ memcpy(new, dst, dstlen);
+ strcat(new, src);
+
+ // Free old one
+ if( clean-- ) {
+ free(dst);
+
+ if( clean ) {
+ free(src);
+ }
+ }
+ return new;
+}
+
+// Trace node
+
+%}
+
+%token IFF EELSE FFOR RP RCP RSP LP LCP LSP ID COLON CMP NO WHILE
+
+%union {
+ char *string;
+ struct ast_node *node;
+ struct cond *condition;
+ uint8_t cmp;
+}
+
+%type <string> ID
+%type <node> statement stm_list
+%type <cmp> CMP
+%type <condition> condition
+
+%%
+
+program: stm_list {gentree(stdout, NULL, $1);printf("\n");};
+
+stm_list: statement { $$ = $1; }
+ | stm_list statement { $$ = insert_stm($2, $1); };
+
+condition: ID CMP ID { $$ = insert_cond($2, $1, $3); }
+ | ID { $$ = insert_cond(CNEQ, $1, "0");};
+
+statement: ID {$$ = insert_ident($1);}
+ | IFF LP condition RP LCP stm_list RCP {$$ = insert_ctrl(TIF, $3, $6, NULL);}
+ | IFF LP condition RP LCP stm_list RCP EELSE LCP stm_list RCP {$$ = insert_ctrl(TIF, $3, $6, $10);}
+ | WHILE LP condition RP LCP stm_list RCP {$$ = insert_ctrl(TWHILE, $3, $6, NULL);}
+ | FFOR LP ID LP condition LP ID RP LCP stm_list RCP {$$ = insert_for($3, $5, $7, $10);};
+
+%%
+
+
+int main() {
+
+ /*for(;;) {
+ int t = yylex();
+ printf("yylex: %d\n", t);
+ } */
+
+ yyparse();
+}
+
diff --git a/sem3/osc/miniproject/cnasm/test.asm b/sem3/osc/miniproject/cnasm/test.asm
new file mode 100644
index 0000000..77a3572
--- /dev/null
+++ b/sem3/osc/miniproject/cnasm/test.asm
@@ -0,0 +1,39 @@
+global _start
+
+section .data
+ align 2
+ ; String, which is just a collection of bytes, 0xA is newline
+ str: db 'Hello, world!',0xA
+ strLen: equ $-str
+
+section .bss
+
+section .text
+ _start:
+
+ mov edx, strLen ; Arg three: the length of the string
+ mov ecx, str ; Arg two: the address of the string
+ mov ebx, 1 ; Arg one: file descriptor, in this case stdout
+ mov eax, 4 ; Syscall number, in this case the
+ int 0x80 ; Interrupt 0x80
+
+ if ( hej = 10 ) {
+ mov ebx, 0 ; Arg one: the status
+ mov eax, 1 ; Syscall number:
+ if(cool) {
+ int 0x80
+ }
+ } else {
+ while( lol ) {
+ mov hej, 0
+ }
+ }
+ while( lol ) {
+ mov hej, 0
+ }
+
+ hej
+
+ for(mov a, 0( a < 100( a++ ) {
+ test
+ }
diff --git a/sem3/osc/mm1/.gitignore b/sem3/osc/mm1/.gitignore
new file mode 100644
index 0000000..b18a498
--- /dev/null
+++ b/sem3/osc/mm1/.gitignore
@@ -0,0 +1,10 @@
+jmod.ko
+.jmod.ko.cmd
+jmod.mod.c
+jmod.mod.o
+.jmod.mod.o.cmd
+jmod.o
+.jmod.o.cmd
+modules.order
+Module.symvers
+.tmp_versions
diff --git a/sem3/osc/mm1/mm1/Makefile b/sem3/osc/mm1/mm1/Makefile
new file mode 100644
index 0000000..13c8e62
--- /dev/null
+++ b/sem3/osc/mm1/mm1/Makefile
@@ -0,0 +1,7 @@
+obj-m += jmod.o
+
+all:
+ make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
+clean:
+ make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean
+
diff --git a/sem3/osc/mm1/mm1/Readme.md b/sem3/osc/mm1/mm1/Readme.md
new file mode 100644
index 0000000..fcc6cb3
--- /dev/null
+++ b/sem3/osc/mm1/mm1/Readme.md
@@ -0,0 +1,34 @@
+# Opgaver til operativ systemer
+
+Ligenu er det ikke delt op i mapper.
+
+## Kør mini kernel modul
+
+Compile med make.
+Husk at peg makefile på din kernel modul mappe.
+Denne er testet på ubuntu server 19.04.
+
+```
+make
+```
+
+Nu burde der være kommet et jmod.ko som kan loades med.
+
+```
+sudo insmod jmod.ko
+```
+
+Hvis du får permission denied kan du få flere information ved at checke `dmesg` loggen.
+
+Nu kan du hente major number ind fra dmesg. Led efter `COOL_MODULE:`.
+Dette nummer bruger du til at assign den en node
+
+```
+sudo mknod /dev/cooldev c MAJOR 0
+```
+
+Dette vil map kernel-modul/driver til cooldev i /dev/ mappen.
+Husk at skriv til MAJOR nummer fra `dmesg` i stedet for MAJOR.
+
+Hvis man læser man pagen kan man se at det bliver lavet som en character unbuffered file.
+MINOR nummeret er 0 da vores driver alligevel ikke bruger det til noget.
diff --git a/sem3/osc/mm1/mm1/jmod.c b/sem3/osc/mm1/mm1/jmod.c
new file mode 100644
index 0000000..a07077c
--- /dev/null
+++ b/sem3/osc/mm1/mm1/jmod.c
@@ -0,0 +1,70 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+
+static int major_num;
+static int busy;
+
+
+static int cool_open(struct inode *inode, struct file *file) {
+ /* Check if we are already serving someone */
+ if (busy) {
+ return -EBUSY;
+ }
+
+ busy = 1;
+ return 0;
+}
+
+static int cool_release (struct inode *inode, struct file *file) {
+ busy = 0;
+
+ return 0;
+}
+
+static ssize_t cool_read (struct file *filp, char *buffer, size_t len, loff_t *offset) {
+
+ char str[12] = "hej med dig";
+ int i;
+
+ for (i = 0; i < len; i++) {
+ put_user(str[i % 12], buffer++);
+ }
+
+ return i;
+}
+
+static struct file_operations file_ops = {
+ .owner = THIS_MODULE,
+ .read = cool_read,
+ .open = cool_open,
+ .release = cool_release
+};
+
+static int __init jmod_init(void)
+{
+ printk(KERN_INFO "COOL_MODULE: Registering cooldev\n");
+
+ major_num = register_chrdev(0, "cooldev", &file_ops);
+ if (major_num < 0) {
+ printk(KERN_ERR "COOL_MODULE: Could not register major\n");
+ return 1;
+ }
+
+ printk(KERN_INFO "COOL_MODULE: Got major %d\n", major_num);
+
+ return 0;
+}
+
+
+static void __exit jmod_exit(void)
+{
+ printk(KERN_INFO "COOL_MODULE: Nou moe\n");
+ unregister_chrdev(major_num, "cooldev");
+}
+
+module_init( jmod_init );
+module_exit( jmod_exit );
+
diff --git a/sem3/osc/mm1/mm2/tprog.c b/sem3/osc/mm1/mm2/tprog.c
new file mode 100644
index 0000000..377555f
--- /dev/null
+++ b/sem3/osc/mm1/mm2/tprog.c
@@ -0,0 +1,71 @@
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#define STARTSEC 10
+#define ENDUSEC 500000
+#define SPEED 0.8
+
+struct itimerval timer;
+
+void timer_handler(int signum) {
+ /* Handy structure reference */
+ struct timeval *tv = &timer.it_value;
+ printf("Hey we hit the alarm\n\a");
+
+ /* Calculate new alarm */
+ tv->tv_sec *= SPEED;
+ if (tv->tv_sec == 0) {
+ /* If tv_usec is 0 set i to 1 sec otherwise half it */
+ if (tv->tv_usec == 0) {
+ tv->tv_usec = 999999;
+ } else if (tv->tv_usec > ENDUSEC) {
+ tv->tv_usec *= SPEED;
+ if (tv->tv_usec < ENDUSEC) {
+ tv->tv_usec = ENDUSEC;
+ }
+ } else {
+ /* Return letting the timer be set to ENDUSEC */
+ return;
+ }
+ }
+
+ printf("Set to %d and %d\n", timer.it_value.tv_sec, timer.it_value.tv_usec);
+ /* Set alarm */
+ int err = setitimer(ITIMER_REAL, &timer, NULL);
+ if (err) {
+ printf("Hey we got an error guys\n");
+ exit(1);
+ }
+}
+
+int main() {
+ /* Setup handler for timer */
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa)); /* Remeber to set all fields to zero */
+
+ sa.sa_handler = &timer_handler;
+ sigaction(SIGALRM, &sa, NULL);
+
+ /* Setup timer values */
+ timer.it_value.tv_sec = STARTSEC;
+ timer.it_value.tv_usec = 0;
+
+ timer.it_interval.tv_sec = 0;
+ timer.it_interval.tv_usec = ENDUSEC;
+
+ /* Start the timer */
+ setitimer(ITIMER_REAL, &timer, NULL);
+
+ /* Select signals */
+ sigset_t sigset;
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGTERM);
+
+ /* Wait for termination */
+ sigwait(&sigset, NULL);
+
+ return 0;
+}
diff --git a/sem3/osc/mm10/Makefile b/sem3/osc/mm10/Makefile
new file mode 100644
index 0000000..99bd635
--- /dev/null
+++ b/sem3/osc/mm10/Makefile
@@ -0,0 +1,25 @@
+opgaver=opg1 opg3 opg4
+
+LEX=flex
+CC=gcc
+LINKFLAG=-lfl
+DEFAULT_TARGET=all
+
+%: %.yy.c
+ $(CC) -o $@ $^ $(LINKFLAG)
+
+%.o: %.c
+ $(CC) -c -o $@ $^
+
+%.yy.c: %.l
+ $(LEX) -o $@ $^
+
+all: $(opgaver)
+
+phony: all clean run
+
+run: $(BIN)
+ ./$(BIN)
+
+clean:
+ rm -f $(opgaver)
diff --git a/sem3/osc/mm10/opg1.l b/sem3/osc/mm10/opg1.l
new file mode 100644
index 0000000..b5cb478
--- /dev/null
+++ b/sem3/osc/mm10/opg1.l
@@ -0,0 +1,22 @@
+%{
+
+#include <stdio.h>
+
+%}
+
+ting (a|b)abcd
+
+%%
+
+{ting} { printf("Fandt ting %s\n", yytext); return 1; }
+. { printf("Meh"); }
+
+%%
+
+int main(void) {
+
+ printf("yylex: %d\n", yylex());
+
+ return 0;
+
+}
diff --git a/sem3/osc/mm10/opg3.l b/sem3/osc/mm10/opg3.l
new file mode 100644
index 0000000..1c4b9c7
--- /dev/null
+++ b/sem3/osc/mm10/opg3.l
@@ -0,0 +1,36 @@
+%{
+
+#include <stdio.h>
+
+#define BEGIN_T 1
+#define END_T 2
+#define NUM_T 3
+#define VAR_T 4
+
+%}
+
+VAR [a-zA-Z][a-zA-Z\_\-0-9]*
+TAL [0-9]+
+
+%%
+
+begin {printf("Found a BEGIN\n"); return BEGIN_T;}
+end {printf("Found a END\n"); return END_T;}
+{VAR} {printf("Found a variable %s\n", yytext); return VAR_T;}
+{TAL} {printf("Found a number %d\n", strtol(yytext, NULL, 10)); return NUM_T;}
+
+%%
+
+int main(void) {
+
+ for(;;) {
+ int t = yylex();
+ printf("yylex: %d\n", t);
+ if( t == END_T ) {
+ break;
+ }
+ }
+
+ return 0;
+
+}
diff --git a/sem3/osc/mm10/opg4.l b/sem3/osc/mm10/opg4.l
new file mode 100644
index 0000000..aeb73b1
--- /dev/null
+++ b/sem3/osc/mm10/opg4.l
@@ -0,0 +1,101 @@
+%{
+
+#include <stdio.h>
+#include <stdint.h>
+
+#define BEGIN_T 1
+#define END_T 2
+#define NUM_T 3
+#define VAR_T 4
+#define HASHSIZE 100
+
+typedef struct symnode_struct {
+ struct symnode_struct *next;
+ char *name;
+} symnode_t;
+
+symnode_t *sym_insert(char *var);
+symnode_t *sym_lookup(char *var);
+
+%}
+
+VAR [a-zA-Z][a-zA-Z\_\-0-9]*
+TAL [0-9]+
+
+%%
+
+begin {printf("Found a BEGIN\n"); return BEGIN_T;}
+end {printf("Found a END\n"); return END_T;}
+{VAR} {printf("Found a variable %s\n", yytext);
+ if( !sym_lookup(yytext) ) {
+ printf("Not found inserting\n");
+ sym_insert(yytext);
+ }
+ return VAR_T;}
+{TAL} {printf("Found a number %d\n", strtol(yytext, NULL, 10)); return NUM_T;}
+
+%%
+
+symnode_t *symlist[HASHSIZE];
+
+unsigned int hash(char *s) {
+ uint32_t hv = 0;
+ for( int i = 0; s[i] != '\0'; i++ ) {
+ // take MSB 6 bits of hv and xors with LSB of s[i]
+ uint32_t v = ( hv >> 26 ) ^ (s[i] & 0x3f);
+
+ // Push those back on hv
+ hv = (hv << 4) | v;
+ }
+ // Return appropriate size
+ return hv % HASHSIZE;
+}
+
+
+symnode_t *sym_insert(char *var) {
+ unsigned int index = hash(var);
+
+ // Save old value
+ symnode_t *oldSym = symlist[index];
+
+ // Make new
+ symlist[index] = malloc(sizeof(symnode_t));
+ if( symlist[index] == NULL ) {
+ // If malloc failed
+ symlist[index] = oldSym;
+ return NULL;
+ }
+
+ // Link old one
+ symlist[index]->next = oldSym;
+ symlist[index]->name = var;
+
+ return symlist[index];
+}
+
+symnode_t *sym_lookup(char *var) {
+ unsigned int index = hash(var);
+ symnode_t *n = symlist[index];
+
+ // Look trough list
+ while(n != NULL && strcmp(n->name, var) != 0) {
+ n = n->next;
+ }
+
+ return n;
+}
+
+
+int main(void) {
+
+ for(;;) {
+ int t = yylex();
+ printf("yylex: %d\n", t);
+ if( t == END_T ) {
+ break;
+ }
+ }
+
+ return 0;
+
+}
diff --git a/sem3/osc/mm10/opgaver.md b/sem3/osc/mm10/opgaver.md
new file mode 100644
index 0000000..b8c8186
--- /dev/null
+++ b/sem3/osc/mm10/opgaver.md
@@ -0,0 +1,55 @@
+# MM10
+
+## Opgave 1
+
+A)
+
+<img src="./stateMachine.png"></img>
+
+B)
+
+Kan ses i den tilhørende opg1.l fil.
+For at compile kør:
+
+```
+make run BIN=opg1
+```
+
+C)
+
+```
+aabcd
+
+Fandt ting aabcd
+yylex: 1
+```
+
+```
+afggfd
+
+MehMehMehMehMehMeh
+```
+
+## Opgave 2
+
+Regulære udtryk for:
+
+```
+c kommentarer: \/\/.*\n
+real konstant: [-+]?[0-9]*(\.[0-9]+)?(e\+[0-9]+)?
+starter med store: [A-Z][a-zA-z]+
+```
+
+## Opgave 3
+
+Dette laver jeg i opg3.l filen.
+
+## Opgave 4
+
+Se opg4.l fil og kør med.
+
+```
+make run BIN=opg4
+```
+
+
diff --git a/sem3/osc/mm10/stateMachine.png b/sem3/osc/mm10/stateMachine.png
new file mode 100644
index 0000000..08c5bf2
--- /dev/null
+++ b/sem3/osc/mm10/stateMachine.png
Binary files differ
diff --git a/sem3/osc/mm11/opgaver.md b/sem3/osc/mm11/opgaver.md
new file mode 100644
index 0000000..276236a
--- /dev/null
+++ b/sem3/osc/mm11/opgaver.md
@@ -0,0 +1,32 @@
+# Opgave 1
+
+Mange af dem er okay.
+
+```
+<program> ::= 'program''(' <ident> ')' <statementlist> 'end'.
+<statementlist> ::= <statement> <statementlist> | e
+<statement> ::= <ident> '=' <exp>;
+
+<exp> ::= <term> <expB>
+<expB> ::= <termopr> <term> <expB> | e
+
+<term> ::= <factor> <termB>
+<termB> ::= <factoropr> <factor> <termB> | e
+<termopr> ::= '+' | '-'
+
+<factor> ::= '(' <exp> ')' | <ident>
+<factoropr> ::= '*' | '/'
+```
+
+# Opgave 2
+
+Denne laver jeg måske senere.
+
+# Opgave 3
+
+Denne er løst i regn mappen.
+Kør `make run` deri for at køre.
+
+# Opgave 4
+
+I regn2 mappen
diff --git a/sem3/osc/mm11/regn/Makefile b/sem3/osc/mm11/regn/Makefile
new file mode 100644
index 0000000..442feba
--- /dev/null
+++ b/sem3/osc/mm11/regn/Makefile
@@ -0,0 +1,30 @@
+
+LEX=flex
+YACC=bison
+LIBS=-ly -lfl -lm
+CC=gcc
+
+PROG=regn
+TRASH=lex.yy.c $(PROG).tab.c $(PROG) $(PROG).tab.h $(PROG).output
+
+$(PROG): $(PROG).tab.o lex.yy.o symtab.o
+ $(CC) -o $@ $^ $(LIBS)
+
+$(PROG).tab.c $(PROG).tab.h: $(PROG).y
+ $(YACC) -d -v $(PROG).y
+
+lex.yy.c: $(PROG).l
+ $(LEX) $(PROG).l
+
+%.o: %.c
+ $(CC) -c -o $@ $^
+
+PHONY: clean run
+
+run: $(PROG)
+ ./$(PROG)
+
+clean:
+ rm -f *.o
+ rm -f $(TRASH)
+
diff --git a/sem3/osc/mm11/regn/regn.l b/sem3/osc/mm11/regn/regn.l
new file mode 100644
index 0000000..bbaadb8
--- /dev/null
+++ b/sem3/osc/mm11/regn/regn.l
@@ -0,0 +1,40 @@
+%{
+#include <math.h>
+#include <string.h>
+#include "symtab.h"
+#include "regn.tab.h"
+%}
+
+realtal ([0-9]+|([0-9]*\.[0-9]+))([eE][-+]?[0-9]+)?
+var_begin let
+op_log log
+op_exp exp
+op_sqrt sqrt
+var [A-Za-z][A-Za-z0-9]*
+
+%%
+{realtal} {yylval.dval = atof(yytext);
+ return TAL;}
+{var_begin} {return VAR_BEGIN;}
+{op_log} {return LOG;}
+{op_exp} {return EXP;}
+{op_sqrt} {return SQRT;}
+
+{var} {yylval.string = strdup(yytext); return VAR;}
+
+[ \t] ;
+
+
+'$' {return 0;}
+
+\n|. {return yytext[0];}
+
+%%
+
+void init_sym()
+{
+ int i;
+ for (i = 0; i < HASHSIZE; i++)
+ symbolarray[i] = NULL;
+}
+
diff --git a/sem3/osc/mm11/regn/regn.y b/sem3/osc/mm11/regn/regn.y
new file mode 100644
index 0000000..d0f67eb
--- /dev/null
+++ b/sem3/osc/mm11/regn/regn.y
@@ -0,0 +1,54 @@
+%{
+#include <stdio.h>
+#include <math.h>
+#include "symtab.h"
+#include <string.h>
+%}
+
+%union {
+ char *string;
+ double dval;
+}
+
+%token <string> VAR
+%token <dval> TAL
+%token LOG EXP SQRT VAR_BEGIN
+
+%left '-' '+'
+%right LOG EXP SQRT
+%left '*' '/'
+%right UMINUS
+
+%type <dval> expression
+
+%%
+
+statement_list: statement '\n'
+ | statement_list statement '\n' ;
+
+statement: expression {printf("= %f\n",$1);}
+ | VAR_BEGIN VAR '=' expression {symnode_t *n = sym_lookup($2);
+ if( !n ) {n = sym_insert($2); }
+ n->value = $4;};
+
+expression: expression '+' expression {$$ = $1 + $3;}
+ | expression '-' expression {$$ = $1 - $3;}
+ | expression '*' expression {$$ = $1 * $3;}
+ | expression '/' expression {if ($3 == 0.0)
+ yyerror("divide dy zero");
+ else $$ = $1 / $3;}
+ | '-' expression %prec UMINUS {$$ = - $2;}
+ | '(' expression ')' {$$= $2;}
+ | LOG expression {$$ = log($2);}
+ | EXP expression {$$ = exp($2);}
+ | SQRT expression {$$ = sqrt($2);}
+ | TAL {$$ = $1;}
+ | VAR {symnode_t *n = sym_lookup($1);
+ if( !n ) { yyerror("Var not found"); } else { $$ = n->value;} };
+%%
+
+int main()
+{
+ yyparse();
+}
+
diff --git a/sem3/osc/mm11/regn/symtab.c b/sem3/osc/mm11/regn/symtab.c
new file mode 100644
index 0000000..8103203
--- /dev/null
+++ b/sem3/osc/mm11/regn/symtab.c
@@ -0,0 +1,50 @@
+#include "symtab.h"
+#include <stdlib.h>
+#include <string.h>
+
+unsigned int hash(char *s) {
+ uint32_t hv = 0;
+ for( int i = 0; s[i] != '\0'; i++ ) {
+ // take MSB 6 bits of hv and xors with LSB of s[i]
+ uint32_t v = ( hv >> 26 ) ^ (s[i] & 0x3f);
+
+ // Push those back on hv
+ hv = (hv << 4) | v;
+ }
+ // Return appropriate size
+ return hv % HASHSIZE;
+}
+
+
+symnode_t *sym_insert(char *var) {
+ unsigned int index = hash(var);
+
+ // Save old value
+ symnode_t *oldSym = symbolarray[index];
+
+ // Make new
+ symbolarray[index] = malloc(sizeof(symnode_t));
+ if( symbolarray[index] == NULL ) {
+ // If malloc failed
+ symbolarray[index] = oldSym;
+ return NULL;
+ }
+
+ // Link old one
+ symbolarray[index]->next = oldSym;
+ symbolarray[index]->name = var;
+
+ return symbolarray[index];
+}
+
+symnode_t *sym_lookup(char *var) {
+ unsigned int index = hash(var);
+ symnode_t *n = symbolarray[index];
+
+ // Look trough list
+ while(n != NULL && strcmp(n->name, var) != 0) {
+ n = n->next;
+ }
+
+ return n;
+}
diff --git a/sem3/osc/mm11/regn/symtab.h b/sem3/osc/mm11/regn/symtab.h
new file mode 100644
index 0000000..c61f3a8
--- /dev/null
+++ b/sem3/osc/mm11/regn/symtab.h
@@ -0,0 +1,20 @@
+#include <stdint.h>
+#define HASHSIZE 100
+
+typedef struct symnode_struct {
+ char *name;
+ struct symnode_struct *next;
+ double value;
+} symnode_t;
+
+symnode_t *sym_insert(char *var);
+symnode_t *sym_lookup(char *var);
+
+struct symnode {
+ struct symnode *next;
+ char *name;
+ int type;
+ double value;
+};
+
+symnode_t *symbolarray[HASHSIZE];
diff --git a/sem3/osc/mm11/regn2/Makefile b/sem3/osc/mm11/regn2/Makefile
new file mode 100644
index 0000000..9640aaa
--- /dev/null
+++ b/sem3/osc/mm11/regn2/Makefile
@@ -0,0 +1,30 @@
+
+LEX=flex
+YACC=bison
+LIBS=-ly -lfl -lm
+CC=gcc
+
+PROG=regn
+TRASH=lex.yy.c $(PROG).tab.c $(PROG) $(PROG).tab.h $(PROG).output
+
+$(PROG): $(PROG).tab.o lex.yy.o
+ $(CC) -o $@ $^ $(LIBS)
+
+$(PROG).tab.c $(PROG).tab.h: $(PROG).y
+ $(YACC) -d -v $(PROG).y
+
+lex.yy.c: $(PROG).l
+ $(LEX) $(PROG).l
+
+%.o: %.c
+ $(CC) -c -o $@ $^
+
+PHONY: clean run
+
+run: $(PROG)
+ ./$(PROG)
+
+clean:
+ rm -f *.o
+ rm -f $(TRASH)
+
diff --git a/sem3/osc/mm11/regn2/regn.l b/sem3/osc/mm11/regn2/regn.l
new file mode 100644
index 0000000..9988ddd
--- /dev/null
+++ b/sem3/osc/mm11/regn2/regn.l
@@ -0,0 +1,27 @@
+%{
+#include <math.h>
+#include <string.h>
+#include "regn.tab.h"
+%}
+
+realtal ([0-9]+|([0-9]*\.[0-9]+))([eE][-+]?[0-9]+)?
+op_log log
+op_exp exp
+op_sqrt sqrt
+
+%%
+{realtal} {yylval.dval = atof(yytext);
+ return TAL;}
+{op_log} {return LOG;}
+{op_exp} {return EXP;}
+{op_sqrt} {return SQRT;}
+
+[ \t] ;
+
+
+'$' {return 0;}
+
+\n|. {return yytext[0];}
+
+%%
+
diff --git a/sem3/osc/mm11/regn2/regn.y b/sem3/osc/mm11/regn2/regn.y
new file mode 100644
index 0000000..eac24c8
--- /dev/null
+++ b/sem3/osc/mm11/regn2/regn.y
@@ -0,0 +1,46 @@
+%{
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+%}
+
+%union {
+ double dval;
+}
+
+%token <dval> TAL
+%token LOG EXP SQRT
+
+%left '-' '+'
+%left LOG EXP SQRT
+%left '*' '/'
+%right UMINUS
+
+%type <dval> expression
+
+%%
+
+statement_list: statement '\n'
+ | statement_list statement '\n' ;
+
+statement: expression {printf("out \n");};
+
+expression: expression '+' expression {printf("sum \n");}
+ | expression '-' expression {printf("sub \n");}
+ | expression '*' expression {printf("mul \n");}
+ | expression '/' expression {if ($3 == 0.0)
+ yyerror("divide dy zero");
+ else printf("div \n");}
+ | '-' expression %prec UMINUS {printf("neg \n");}
+ | '(' expression ')' {;}
+ | LOG expression {printf("log \n");}
+ | EXP expression {printf("exp \n");}
+ | SQRT expression {printf("sqrt \n");}
+ | TAL {printf("load %f \n", $$);};
+%%
+
+int main()
+{
+ yyparse();
+}
+
diff --git a/sem3/osc/mm3/opgaver.md b/sem3/osc/mm3/opgaver.md
new file mode 100644
index 0000000..d9440f8
--- /dev/null
+++ b/sem3/osc/mm3/opgaver.md
@@ -0,0 +1,47 @@
+# Opgave 1
+
+> Et operativsystem anvenderen 2-level page tabel og 4Kbyte pagesize. Det
+virtuelle adresseområde er på 4GByte. De programmer der afvikles på
+computeren er på mellem 64 KByte og 16MByte. Hvor mange bit vil I anvende til
+index ind i hhv. page tabel 1 og pagetabel 2.
+
+Her betyder det at man har en tabel der referere til level 2 tabeller.
+
+Så i level to tabellen ville jeg nok have 4M da det er 1023 pages.
+Dette betyder at der vil lidt spild med det lille program på 64kb men det større program på 16Mb betøver ikke få så mange pages.
+
+1023 pages kræver tilgængeld 10 bits til indexering hvilket er lidt spild.
+
+For at få op til 4GB skal man igen have 1023 reference i level 1 tabel.
+
+En anden mulighed ville være at have 8 bits til level 2 index, og derfor have 255 pages i level to tabel.
+Dette vil betyde at level to indexen ikke spilder plads from med 10 bit.
+
+En level 1 tabel indexer derfor 4Kb * 255 = 4096 * 255 = 104 4480 = 104Kb
+
+Her vil level 1 tabellen få 4Gb / 104.4480Kb = 4 000 000 000 / 104 4480 =~= 4112
+
+Her skal man bruge 13 bits, hvilket betyder at man spilder 3 bits hvis man bruger 16 bit system.
+
+# Opgave 2
+
+> Diskuter måder at håndtere virtuelle pages på. Kan man optimere software i
+forhold til hvordan et OS håndterer pages? Er der noget i en eller flere
+koncepter I måske kan anvende i jeres projekt?
+
+Læser på wikipedia at dette er en teknik hvor man gemmer under pagene i virtuel memory i stedet for physical.
+Dette vil betyder at den også kan blive swappet til disk osv.
+
+Dette vil tilgengeld kræve at man har nogle pages i physical som skal holder styr på de virtuelle som indeholder andre pages.
+Det vil nok egentlig være lidt bøvlet.
+
+Man kunne måske have at level 1 tabellen signalere om pagen er i physical eller virtuel.
+
+# Opgave 3
+
+> Skriv et lille program, der allokerer en stadig voksende mængde hukommelse,
+f.eks. start med 8kB, 8MB, 8GB og mere... hvornår løber I ind i problemer?
+Observer evt. med værktøjet ovenstående eller andet der passer til jeres
+platform.
+
+
diff --git a/sem3/osc/mm8/mm8.ino b/sem3/osc/mm8/mm8.ino
new file mode 100644
index 0000000..f47306d
--- /dev/null
+++ b/sem3/osc/mm8/mm8.ino
@@ -0,0 +1,47 @@
+// Spg kernel
+#include <krnl.h>
+
+#define PRIO 10
+#define STACK 100
+
+char stackFast[STACK];
+struct k_t *semFast, *fastTask;
+
+void fast() {
+ /* Gotta go fast(10 Hz) */
+ k_set_sem_timer(semFast, 1000);
+ for(;;) {
+ k_wait(semFast, 0);
+ k_eat_ticks(90);
+ }
+}
+
+void setup() {
+ pinMode(13, OUTPUT);
+
+ PORTB |= 0x20;
+ delay(1000);
+ PORTB &= 0xDF;
+ delay(200);
+
+ k_init(1, 1, 0);
+
+ fastTask = k_crt_task(fast, PRIO, stackFast, STACK);
+ semFast = k_crt_sem(0, 2);
+
+ k_start(1);
+ PORTB |= 0x20;
+}
+
+void loop() {}
+
+extern "C" {
+
+ void k_breakout() {
+ if( pRun->nr == 0 ) {
+ PORTB |= 0x20;
+ } else {
+ PORTB &= 0xDF;
+ }
+ }
+}
diff --git a/sem3/osc/mm9/opgaver.md b/sem3/osc/mm9/opgaver.md
new file mode 100644
index 0000000..fe2ec99
--- /dev/null
+++ b/sem3/osc/mm9/opgaver.md
@@ -0,0 +1,129 @@
+# Opgave A
+
+Hmm ved ikke lige med projekt men har en fed ide.
+
+Openscad men til 2d graffik som **kompilere** til svg.
+
+Tænker at man vil lave det i et sprog som c, go eller rust.
+Rust ville være optimalt men det er også lidt svært.
+
+Det skulle være et emperisk sprog med variabler og functioner.
+Funktioner returnere ikke noget, men mere en bestemt figur.
+
+Variables can be strings, floating point numbers.
+
+Lists are defined as list.
+
+Strings begin with big letters.
+
+Bools are defined as numbers 0 and 1.
+
+Lists are defined as [] and contain all numbers or all strings.
+
+C style comments.
+
+```
+var Black = "#FFFFFF";
+var White = "#000000";
+list Names = [ "nice", "nice2" ];
+
+var radius = 10.2;
+
+func coolCircle(r, Name) {
+ // Defined as circle(radius, fgCol, bgCol)
+ circle(r, Black, White);
+
+ // Defined as insertText(Text, allign, fgCol)
+ insertText(Name, ALIGN_CENTER, Black);
+}
+
+translate(1, 2) {
+ coolCircle(radius / 2, Names[0]);
+}
+
+coolCircle(radius, Names[1]);
+```
+
+The code will generate two circles, one in the center and one on the coordinates 1, 2.
+
+# Opgave B
+
+Der er defineret to globale variabler, men de er ikke på stacken.
+
+Inde i main laver man en pointer til a og sender ind i funktionen.
+Dette betyder at denne pointer enten ligger på stacken eller i et register når funktionen ainc kører.
+
+Men der kan siges sikkert at stacken indeholder en return pointer til main og en reference til den tidelige stack(tror jeg).
+
+
+## Kode i assembly
+
+Jeg har ikke taget højde for integer operationer.
+
+```
+JMP main
+var_a: DB 4
+
+ainc:
+ MOV B, [A]
+ ADD B, 1
+ MOV [A], B
+ RET
+
+main:
+ MOV A, var_a
+ CALL ainc
+
+ HLT
+```
+
+## Forskellige compile trin
+
+Proprocessor har ikke noget at lave.
+
+Start med at compile til assembly:
+
+Læg a og b i starten af programmet.
+
+Compiler funktionen ainc og adec og sæt en label ved dem.
+Dette gøres ved først at lave koden der henter argument ud og gemmer tidligere stack pointer.
+Derefter compiles indholdet i funktionen.
+Slut af med at returner til caller.
+
+Derefter bliver assembly'en assemblet:
+
+De forskellige mnenorics(eller hvad det nu hed) bliver lavet om til opcodes og lags sammen med deres argumenter.
+Dette gøres for alle funktionerne.
+
+a og b bliver placeret i filen.
+
+Derefter placeres main ved entrypoint og de to funktioner bliver lagt ved siden af.
+De forskellige referencer til funktioner og globale variabler bliver byttet ud med deres virkelige værdier i binary.
+
+# Opgave C
+
+Grammastart -> *Viggo* stmList *End*
+stmList -> stm stmList | e
+stm -> ident *=* exp *;*
+ident -> letter symList
+letter -> *a* | ... | *å* | *A* | ... | *Å*
+digit -> *0* | ... | *9*
+symbol -> letter | digit
+symList -> symbol symList | e
+exp -> term expB
+expB -> termopr term expB | e
+termOpr -> *+* | *-*
+term -> factor termB
+termB -> factorOpr factor termB | e
+factorOpr -> _*_ | _/_
+factor -> *(* exp *)* | ident
+
+## C.2
+
+See tree.png
+
+## C.3
+
+
+
+
diff --git a/sem3/osc/noter.md b/sem3/osc/noter.md
new file mode 100644
index 0000000..6e13640
--- /dev/null
+++ b/sem3/osc/noter.md
@@ -0,0 +1,17 @@
+# HUsk
+
+Ikke Deterministisk: Et stadie i kan føre til flere andre states.
+
+Undersøg **kontekst fri**
+
+Leksikal analysen: bruger regulær
+
+Parsing: ikke regulær.
+
+Shift-reduce parser.
+
+3 adress code bruges til mellem kode.
+
+In order: tree (venstre, top, højre)
+preorder: tree (top, venstre, højre)
+postorder: tree (venstre, højre, top)