diff options
author | Julian T <julian@jtle.dk> | 2020-02-11 12:24:56 +0100 |
---|---|---|
committer | Julian T <julian@jtle.dk> | 2020-02-11 12:24:56 +0100 |
commit | 6db1a2cdd3b96731f2e092d55d8c2136eabc52d0 (patch) | |
tree | 2be8fae8ce82d708ed9f00f376dda14420850e80 /sem3/osc | |
parent | 57305119e05559c1c37e903aef89cd43f44c42c9 (diff) |
Rename and cleanup
Diffstat (limited to 'sem3/osc')
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 Binary files differnew file mode 100644 index 0000000..08c5bf2 --- /dev/null +++ b/sem3/osc/mm10/stateMachine.png 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) |