summaryrefslogtreecommitdiff
path: root/src/user/app
diff options
context:
space:
mode:
authorAlex AUVOLAT <alexis211@gmail.com>2013-06-08 23:09:52 +0200
committerAlex AUVOLAT <alexis211@gmail.com>2013-06-08 23:09:52 +0200
commit4d65fcb9a8b6c7c6fd5a3390c46a96d11b6a80d4 (patch)
treec193acf64ff2db985f6664f161cf586c3caeb684 /src/user/app
parenteae9997d3c2dbaef53022ddabe61c1800a619499 (diff)
downloadTCE-4d65fcb9a8b6c7c6fd5a3390c46a96d11b6a80d4.tar.gz
TCE-4d65fcb9a8b6c7c6fd5a3390c46a96d11b6a80d4.zip
All FWIK is deleted. YOSH is now pure C. Not-working KBASIC included.
Diffstat (limited to 'src/user/app')
-rw-r--r--src/user/app/fwik.make6
-rw-r--r--src/user/app/init/main.c4
-rw-r--r--src/user/app/kbasic/Makefile9
-rw-r--r--src/user/app/kbasic/basic.h75
-rw-r--r--src/user/app/kbasic/commands.c103
-rw-r--r--src/user/app/kbasic/control.c511
-rw-r--r--src/user/app/kbasic/expr.c153
-rw-r--r--src/user/app/kbasic/kbasic.txt19
-rw-r--r--src/user/app/kbasic/lex.c197
-rw-r--r--src/user/app/kbasic/main.c55
-rw-r--r--src/user/app/kbasic/pppg.bas14
-rw-r--r--src/user/app/kbasic/tables.bas15
-rw-r--r--src/user/app/kbasic/var.c19
-rw-r--r--src/user/app/led/main.c8
-rw-r--r--src/user/app/prime/main.c2
-rw-r--r--src/user/app/test/main.c2
-rw-r--r--src/user/app/yosh/Makefile2
-rw-r--r--src/user/app/yosh/main.c292
-rw-r--r--src/user/app/yosh/main.cpp271
19 files changed, 1471 insertions, 286 deletions
diff --git a/src/user/app/fwik.make b/src/user/app/fwik.make
deleted file mode 100644
index 292440d..0000000
--- a/src/user/app/fwik.make
+++ /dev/null
@@ -1,6 +0,0 @@
-ExtObj = $(SrcPath)/user/lib/fwik/_fwik.o
-
-include $(SrcPath)/common.make
-
-CFLAGS += -I $(SrcPath)/include -I $(SrcPath)/user/lib/libc/include -I $(SrcPath)/user/lib/fwik/include
-LDFLAGS += -T $(SrcPath)/user/link.ld
diff --git a/src/user/app/init/main.c b/src/user/app/init/main.c
index 92fb8f7..bd0b3bf 100644
--- a/src/user/app/init/main.c
+++ b/src/user/app/init/main.c
@@ -1,8 +1,8 @@
#include <tce/syscall.h>
#include <stdio.h>
-int main(char **args) {
- FILE home_term = open("/.ui/home", 0);
+int main(int argc, char **args) {
+ int home_term = open("/.ui/home", 0);
int i, pid;
if (home_term < 0) return -1;
diff --git a/src/user/app/kbasic/Makefile b/src/user/app/kbasic/Makefile
new file mode 100644
index 0000000..22bf991
--- /dev/null
+++ b/src/user/app/kbasic/Makefile
@@ -0,0 +1,9 @@
+Obj = main.o lex.o control.o commands.o var.o expr.o
+Out = kbasic.elf
+
+
+include $(SrcPath)/user/app/common.make
+
+LDFLAGS += -Map kbasic.map
+CFLAGS += -Wno-error=missing-braces
+
diff --git a/src/user/app/kbasic/basic.h b/src/user/app/kbasic/basic.h
new file mode 100644
index 0000000..b3491da
--- /dev/null
+++ b/src/user/app/kbasic/basic.h
@@ -0,0 +1,75 @@
+/* A tiny BASIC interpreter */
+
+/*
+ Thank the Internet for providing me with this program.
+ Please report any bugs/security holes to: katchup@adnab.fr.nf
+*/
+
+#ifndef DEF_BASIC_H
+#define DEF_BASIC_H
+
+
+// Token types
+#define DELIMITER 1
+#define VARIABLE 2
+#define NUMBER 3
+#define COMMAND 4
+#define STRING 5
+#define QUOTE 6
+
+// Keywords
+#define EOL 98 // Special characters
+#define FINISHED 99
+#define IF 1 // Control structures
+#define THEN 2
+#define FOR 3
+#define NEXT 4
+#define TO 5
+#define GOTO 6
+#define GOSUB 7
+#define RETURN 8
+#define END 9
+#define EXEC 10
+#define LOAD 11
+#define RUN 12
+#define LIST 13
+#define PRINT 20 // Built-in commands
+#define INPUT 21
+#define RND 50 // Built-in functions
+
+// Buffer size definitions
+#define TOK_LEN 80
+#define LAB_LEN 10 // Control structures
+#define NUM_LAB 100
+#define FOR_NEST 25
+#define SUB_NEST 25
+
+// Lexer
+extern char *program; // Data for program
+extern char *prog_ip; // Program instructino pointer
+extern char token[TOK_LEN];
+extern int token_type, tok;
+int get_token();
+void putback();
+void find_eol();
+char *load_file(char *fname);
+
+// Data structures
+int* find_var(char *s); // returns a pointer to the variable
+
+// Program structure
+void init();
+extern char *interp_name; /* given by command line argument 0 */
+void load_program(char *); // load and scan labels
+void insert_line(char *l, int n); // add line to program
+int start(char *entry); // start execution at given point
+void serror(int);
+
+// BASIC commands
+void exec_print(), input();
+void assignment();
+void get_exp(int*);
+
+
+#endif
+
diff --git a/src/user/app/kbasic/commands.c b/src/user/app/kbasic/commands.c
new file mode 100644
index 0000000..f60f32a
--- /dev/null
+++ b/src/user/app/kbasic/commands.c
@@ -0,0 +1,103 @@
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "basic.h"
+
+/* Assign a variable a value. */
+void assignment()
+{
+ int *var;
+ int value;
+
+ /* get the variable name */
+ get_token();
+ if(!isalpha(*token)) {
+ serror(4);
+ return;
+ }
+
+ var = find_var(token);
+
+ /* get the equals sign */
+ get_token();
+ if(*token!='=') {
+ serror(3);
+ return;
+ }
+
+ /* get the value to assign to var */
+ get_exp(&value);
+
+ /* assign the value */
+ *var = value;
+}
+
+
+
+/* Execute a simple version of the BASIC PRINT statement */
+void exec_print()
+{
+ int answer;
+ int len=0, spaces;
+ char last_delim;
+
+ do {
+ get_token(); /* get next list item */
+ if(tok==EOL || tok==FINISHED) break;
+ if(token_type==QUOTE) { /* is string */
+ printf("%s", token);
+ len += strlen(token);
+ get_token();
+ }
+ else { /* is expression */
+ putback();
+ get_exp(&answer);
+ get_token();
+ len += printf("%d", answer);
+ }
+ last_delim = *token;
+
+ if(*token==';') {
+ /* compute number of spaces to move to next tab */
+ spaces = 8 - (len % 8);
+ len += spaces; /* add in the tabbing position */
+ while(spaces) {
+ printf(" ");
+ spaces--;
+ }
+ }
+ else if(*token==',') /* do nothing */;
+ else if(tok!=EOL && tok!=FINISHED) serror(0);
+ } while (*token==';' || *token==',');
+
+ if(tok==EOL || tok==FINISHED) {
+ if(last_delim != ';' && last_delim!=',') printf("\n");
+ }
+ else serror(0); /* error is not , or ; */
+
+}
+
+/* Execute a simple form of the BASIC INPUT command */
+void input()
+{
+ int *var;
+ int tmp;
+
+ get_token(); /* see if prompt string is present */
+ if(token_type==QUOTE) {
+ printf("%s", token); /* if so, print it and check for comma */
+ get_token();
+ if(*token!=',') serror(1);
+ get_token();
+ }
+ else printf("? "); /* otherwise, prompt with / */
+
+ var = find_var(token); /* get the input var */
+
+ scanf("%d\n", var); /* read input */
+
+ /* flush input */
+ while ((tmp = getchar()) != '\n' && tmp != EOF);
+}
+
diff --git a/src/user/app/kbasic/control.c b/src/user/app/kbasic/control.c
new file mode 100644
index 0000000..1ab22ff
--- /dev/null
+++ b/src/user/app/kbasic/control.c
@@ -0,0 +1,511 @@
+#include <stdio.h>
+#include <string.h>
+// #include <sys/wait.h>
+// #include <unistd.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <setjmp.h>
+
+#include "basic.h"
+
+struct label {
+ char name[LAB_LEN];
+ char *p; /* points to place to go in source file*/
+};
+struct for_stack {
+ int *var; /* counter variable */
+ int target; /* target value */
+ char *loc;
+};
+
+struct label label_table[NUM_LAB];
+
+char *gstack[SUB_NEST]; /* stack for gosub */
+struct for_stack fstack[FOR_NEST]; /* stack for FOR/NEXT loop */
+
+int ftos; /* index to top of FOR stack */
+int gtos; /* index to top of GOSUB stack */
+
+char *program, *prog_ip; /* holds expression to be analyzed */
+
+char *interp_name;
+
+jmp_buf e_buf; /* hold environment for longjmp() */
+
+char *find_label();
+void scan_labels();
+struct for_stack fpop();
+char *gpop();
+int get_next_label(char *);
+void fpush(struct for_stack);
+void gosub(), greturn(), gpush(char*), label_init();
+void exec_if(), exec_for(), next(), exec_goto();
+void exec_exec(), exec_load();
+void exec_list();
+
+/* initialize variables */
+void init() {
+ program = NULL;
+ prog_ip = NULL;
+ label_init();
+}
+
+/* Load program and scans labels */
+void load_program (char *p_buf) {
+ if (program != NULL) {
+ free(program);
+ }
+
+ program = p_buf;
+ scan_labels(); /* find the labels in the program */
+}
+
+/* Insert line at the right place of program */
+void insert_line(char *l, int n) {
+ char *a, *b, *p;
+ int i_n, t, k;
+
+
+ if (program == NULL) {
+ load_program(strdup(l));
+ } else {
+ int prog_l = strlen(program);
+
+ // lookup insert position
+ // find smallest label above line number
+ a = (n == 0 ? program : program + prog_l);
+ i_n = -1; b = program + prog_l;
+
+ for (t = 0; t < NUM_LAB; t++) {
+ if (label_table[t].name[0]) {
+ k = atoi(label_table[t].name);
+ if (k == n) {
+ a = label_table[t].p;
+ while (*a != '\n' && a > program) a--; // back to beginning of line
+ if (*a == '\n') a++;
+ }
+ if (k > n && (k < i_n || i_n == -1)) {
+ i_n = k;
+ b = label_table[t].p;
+ while (*b != '\n' && b > program) b--; // back to beginning of line
+ if (*b == '\n') b++;
+ if (b < a) a = b;
+ }
+ }
+ }
+
+ p = malloc(prog_l + strlen(l) + 3);
+
+ strncpy(p, program, (a - program)); // copy [0, a[
+ p[a - program] = 0;
+ // if l is an empty line, do not copy.
+ for (i_n = 0; l[i_n]; i_n++) {
+ if (!isdigit(l[i_n]) && l[i_n] != '\n' && l[i_n] != '\r') {
+ strcpy(p + (a - program), l); // copy l
+ break;
+ }
+ }
+ strcat(p + (a - program), b); // copy [b, end[
+
+ load_program(p); // reparse labels
+ }
+}
+
+/* start program execution at given entry point (not necessarily in loaded program)
+ return values :
+ - 0 : return on end of input
+ - 1 : return on error
+ - 2 : return on "END" statement
+ - 3 : return on "LOAD" statement
+*/
+int start(char *entry) {
+ ftos = 0; /* initialize the FOR stack index */
+ gtos = 0; /* initialize the GOSUB stack index */
+
+ prog_ip = entry;
+ if(setjmp(e_buf)) return 1; /* initialize the long jump buffer */
+
+ do {
+ token_type = get_token();
+ /* check for assignment statement */
+ if(token_type==VARIABLE) {
+ putback(); /* return the var to the input stream */
+ assignment(); /* must be assignment statement */
+ }
+ else /* is command */
+ switch(tok) {
+ case LIST:
+ exec_list();
+ break;
+ case PRINT:
+ exec_print();
+ break;
+ case GOTO:
+ exec_goto();
+ break;
+ case IF:
+ exec_if();
+ break;
+ case FOR:
+ exec_for();
+ break;
+ case NEXT:
+ next();
+ break;
+ case INPUT:
+ input();
+ break;
+ case GOSUB:
+ gosub();
+ break;
+ case RETURN:
+ greturn();
+ break;
+ case EXEC:
+ exec_exec();
+ break;
+ case LOAD:
+ exec_load();
+ return 3;
+ case RUN: // (re)start program at begining
+ ftos = gtos = 0;
+ prog_ip = program;
+ break;
+ case END: // end program execution
+ return 2;
+ }
+ } while (prog_ip != NULL && tok != FINISHED);
+
+ return 0;
+}
+
+/* display an error message */
+void serror(int error)
+{
+ static char *e[]= {
+ "syntax error",
+ "unbalanced parentheses",
+ "no expression present",
+ "equals sign expected",
+ "not a variable",
+ "Label table full",
+ "duplicate label",
+ "undefined label",
+ "THEN expected",
+ "TO expected",
+ "too many nested FOR loops",
+ "NEXT without FOR",
+ "too many nested GOSUBs",
+ "RETURN without GOSUB"
+ };
+ printf ("[near '%s' %d %d] E: %s\n", token, tok, token_type, e[error]);
+
+ longjmp(e_buf, 1); /* return to save point */
+ exit(0);
+
+}
+
+/* Find all labels. */
+void scan_labels()
+{
+ int addr;
+
+ label_init(); /* zero all labels */
+
+ if (program == 0) return; /* if no program is loaded, nothing to do. */
+
+ prog_ip = program; /* prog_ip will go through the program */
+
+ /* if the first token in the file is a label */
+ get_token();
+ if(token_type==NUMBER) {
+ strcpy(label_table[0].name,token);
+ label_table[0].p=prog_ip;
+ }
+
+ find_eol();
+ do {
+ get_token();
+ if(token_type==NUMBER) {
+ addr = get_next_label(token);
+ if(addr==-1 || addr==-2) {
+ (addr==-1) ?serror(5):serror(6);
+ }
+ strncpy(label_table[addr].name, token, LAB_LEN);
+ label_table[addr].name[LAB_LEN-1] = 0; // null terminate
+ label_table[addr].p = prog_ip; /* current point in program */
+ }
+ /* if not on a blank line, find next line */
+ if(tok!=EOL) find_eol();
+ } while(tok!=FINISHED);
+}
+
+/* Return index of next free position in label array.
+ A -1 is returned if the array is full.
+ A -2 is returned when duplicate label is found.
+ */
+int get_next_label(char *s)
+{
+ register int t;
+
+ for(t=0;t<NUM_LAB;++t) {
+ if(label_table[t].name[0]==0) return t;
+ if(!strcmp(label_table[t].name,s)) return -2; /* dup */
+ }
+
+ return -1;
+}
+
+/* Find location of given label. A null is returned if
+ label is not found; otherwise a pointer to the position
+ of the label is returned.
+ */
+char *find_label(char *s)
+{
+ register int t;
+
+ for(t=0; t<NUM_LAB; ++t)
+ if(!strcmp(label_table[t].name,s)) return label_table[t].p;
+ return '\0'; /* error condition */
+}
+
+/* Execute a GOTO statement. */
+void exec_goto()
+{
+
+ char *loc;
+
+ get_token(); /* get label to go to */
+ /* find the location of the label */
+ loc = find_label(token);
+ if(loc=='\0')
+ serror(7); /* label not defined */
+
+ else prog_ip=loc; /* start program running at that loc */
+}
+
+/* Initialize the array that holds the labels.
+ By convention, a null label name indicates that
+ array position is unused.
+ */
+void label_init()
+{
+ register int t;
+
+ for(t=0; t<NUM_LAB; ++t) label_table[t].name[0]='\0';
+}
+
+/* Execute an IF statement. */
+void exec_if()
+{
+ int x , y, cond;
+ char op;
+
+ get_exp(&x); /* get left expression */
+
+ get_token(); /* get the operator */
+ if(!strchr("=<>", *token)) {
+ serror(0); /* not a legal operator */
+ return;
+ }
+ op=*token;
+
+ get_exp(&y); /* get right expression */
+
+ /* determine the outcome */
+ cond = 0;
+ switch(op) {
+ case '<':
+ if(x<y) cond=1;
+ break;
+ case '>':
+ if(x>y) cond=1;
+ break;
+ case '=':
+ if(x==y) cond=1;
+ break;
+ }
+ if(cond) { /* is true so process target of IF */
+ get_token();
+ if(tok!=THEN) {
+ serror(8);
+ return;
+ }/* else program execution starts on next line */
+ }
+ else find_eol(); /* find start of next line */
+}
+
+/* Execute a FOR loop. */
+void exec_for()
+{
+ struct for_stack i;
+ int value;
+
+ get_token(); /* read the control variable */
+ if(!isalpha(*token)) {
+ serror(4);
+ return;
+ }
+
+ i.var=find_var(token); /* save its index */
+
+ get_token(); /* read the equals sign */
+ if(*token!='=') {
+ serror(3);
+ return;
+ }
+
+ get_exp(&value); /* get initial value */
+
+ *(i.var) = value;
+
+ get_token();
+ if(tok!=TO) serror(9); /* read and discard the TO */
+
+ get_exp(&i.target); /* get target value */
+
+ /* if loop can execute at least once, push info on stack */
+ if(value>=*(i.var)) {
+ i.loc = prog_ip;
+ fpush(i);
+ }
+ else /* otherwise, skip loop code altogether */
+ while(tok!=NEXT) get_token();
+}
+
+/* Execute a NEXT statement. */
+void next()
+{
+ struct for_stack i;
+
+ i = fpop(); /* read the loop info */
+
+ (*(i.var))++;
+ if(*(i.var)>i.target) return; /* all done */
+ fpush(i); /* otherwise, restore the info */
+ prog_ip = i.loc; /* loop */
+}
+
+/* Push function for the FOR stack. */
+void fpush(struct for_stack i)
+{
+ if(ftos>FOR_NEST)
+ serror(10);
+
+ fstack[ftos]=i;
+ ftos++;
+}
+
+struct for_stack fpop()
+{
+ ftos--;
+ if(ftos<0) serror(11);
+ return(fstack[ftos]);
+}
+
+/* Execute a GOSUB command. */
+void gosub()
+{
+ char *loc;
+
+ get_token();
+ /* find the label to call */
+ loc = find_label(token);
+ if(loc=='\0')
+ serror(7); /* label not defined */
+ else {
+ gpush(prog_ip); /* save place to return to */
+ prog_ip = loc; /* start program running at that loc */
+ }
+}
+
+/* Return from GOSUB. */
+void greturn()
+{
+ prog_ip = gpop();
+}
+
+/* GOSUB stack push function. */
+void gpush(char *s)
+{
+ gtos++;
+
+ if(gtos==SUB_NEST) {
+ serror(12);
+ return;
+ }
+
+ gstack[gtos]=s;
+
+}
+
+/* GOSUB stack pop function. */
+char *gpop()
+{
+ if(gtos==0) {
+ serror(13);
+ return 0;
+ }
+
+ return(gstack[gtos--]);
+}
+
+
+/* EXEC function
+ Forks and runs another instance of the interpreter
+ */
+void exec_exec() {
+
+ /* TODO
+ int pid;
+
+ get_token();
+ if (token_type==QUOTE) {
+ pid = fork();
+ if (pid < 0) {
+ printf("Error: could not fork.\n");
+ } else {
+ if (pid == 0) {
+ execlp(interp_name, interp_name, token, 0);
+ printf("Error: could not exec.\n");
+ exit(0);
+ } else {
+ wait(0);
+ }
+ }
+ get_token();
+ } else {
+ serror(0);
+ }
+ */
+ printf("EXEC not available.\n");
+}
+
+/* LOAD function
+ loads a program into interpreter and ends anything currently executing */
+void exec_load() {
+ char *p_buf;
+
+ get_token();
+ if (token_type==QUOTE) {
+ if (!(p_buf = load_file(token))) {
+ printf("Error: could not load file %s\n", token);
+ } else {
+ load_program(p_buf);
+ }
+ } else {
+ serror(0);
+ }
+}
+
+/* LIST function
+ dumps program source text */
+void exec_list() {
+ get_token();
+
+ if (program == NULL) {
+ printf("No program loaded.\n");
+ } else {
+ printf("%s", program);
+ }
+}
diff --git a/src/user/app/kbasic/expr.c b/src/user/app/kbasic/expr.c
new file mode 100644
index 0000000..3b8d558
--- /dev/null
+++ b/src/user/app/kbasic/expr.c
@@ -0,0 +1,153 @@
+#include <stdlib.h>
+
+#include "basic.h"
+
+void level2(int*), level3(int*), level4(int*), level5(int*), level6(int*), primitive(int*);
+void unary(char, int*), arith(char, int*, int*);
+
+/* Entry point into parser. */
+void get_exp(int *result)
+{
+ get_token();
+ if(!*token) {
+ serror(2);
+ return;
+ }
+ level2(result);
+ putback(); /* return last token read to input stream */
+}
+
+/* Add or subtract two terms. */
+void level2(int *result)
+{
+ register char op;
+ int hold;
+
+ level3(result);
+ while((op = *token) == '+' || op == '-') {
+ get_token();
+ level3(&hold);
+ arith(op, result, &hold);
+ }
+}
+
+/* Multiply or divide two factors. */
+void level3(int *result)
+{
+ register char op;
+ int hold;
+
+ level4(result);
+ while((op = *token) == '*' || op == '/' || op == '%') {
+ get_token();
+ level4(&hold);
+ arith(op, result, &hold);
+ }
+}
+
+/* Process integer exponent. */
+void level4(int *result)
+{
+ int hold;
+
+ level5(result);
+ if(*token== '^') {
+ get_token();
+ level4(&hold);
+ arith('^', result, &hold);
+ }
+}
+
+/* Is a unary + or -. */
+void level5(int *result)
+{
+ register char op;
+
+ op = 0;
+ if((token_type==DELIMITER) && (*token=='+' || *token=='-')) {
+ op = *token;
+ get_token();
+ }
+ level6(result);
+ if(op)
+ unary(op, result);
+}
+
+/* Process parenthesized expression. */
+void level6(int *result)
+{
+ if((*token == '(') && (token_type == DELIMITER)) {
+ get_token();
+ level2(result);
+ if(*token != ')')
+ serror(1);
+ get_token();
+ }
+ else
+ primitive(result);
+}
+
+/* Find value of number or variable. */
+void primitive(int *result)
+{
+
+ switch(token_type) {
+ case VARIABLE:
+ *result = *find_var(token);
+ get_token();
+ return;
+ case NUMBER:
+ *result = atoi(token);
+ get_token();
+ return;
+ case COMMAND:
+ switch(tok) {
+ case RND:
+ *result = rand();
+ get_token();
+ return;
+ }
+ default:
+ serror(0);
+ }
+}
+
+/* Perform the specified arithmetic. */
+void arith(char o, int *r, int *h)
+{
+ register int t, ex;
+
+ switch(o) {
+ case '-':
+ *r = *r-*h;
+ break;
+ case '+':
+ *r = *r+*h;
+ break;
+ case '*':
+ *r = *r * *h;
+ break;
+ case '/':
+ *r = (*r)/(*h);
+ break;
+ case '%':
+ t = (*r)/(*h);
+ *r = *r-(t*(*h));
+ break;
+ case '^':
+ ex = *r;
+ if(*h==0) {
+ *r = 1;
+ break;
+ }
+ for(t=*h-1; t>0; --t) *r = (*r) * ex;
+ break;
+ }
+}
+
+/* Reverse the sign. */
+void unary(char o, int *r)
+{
+ if(o=='-') *r = -(*r);
+}
+
diff --git a/src/user/app/kbasic/kbasic.txt b/src/user/app/kbasic/kbasic.txt
new file mode 100644
index 0000000..19131ed
--- /dev/null
+++ b/src/user/app/kbasic/kbasic.txt
@@ -0,0 +1,19 @@
+KBASIC commands
+
+EXEC "<filename.bas>" fork and run file in a new process
+LOAD "<filename.bas>" reset interpreter context and load file, ends all execution
+RUN start loaded program at begining
+END end execution of program
+LIST list program text
+
+GOTO <label>
+IF <a> [=><] <b> THEN <expr>
+GOSUB <label>
+RETURN
+FOR <var> = <a> to <b>
+NEXT
+
+PRINT
+INPUT
+
+RND
diff --git a/src/user/app/kbasic/lex.c b/src/user/app/kbasic/lex.c
new file mode 100644
index 0000000..055b502
--- /dev/null
+++ b/src/user/app/kbasic/lex.c
@@ -0,0 +1,197 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "basic.h"
+
+struct commands { /* keyword lookup table */
+ char command[20];
+ char tok;
+} table[] = { /* Commands must be entered lowercase */
+ {"print", PRINT}, /* in this table. */
+ {"input", INPUT},
+
+ {"if", IF},
+ {"then", THEN},
+ {"goto", GOTO},
+ {"for", FOR},
+ {"next", NEXT},
+ {"to", TO},
+ {"gosub", GOSUB},
+ {"return", RETURN},
+
+ {"end", END},
+ {"run", RUN},
+ {"load", LOAD},
+ {"list", LIST},
+ {"exec", EXEC},
+
+ {"rnd", RND},
+ {"", END} /* mark end of table */
+};
+
+char token[TOK_LEN];
+int token_type, tok;
+
+int look_up(char *s); // lookup keyword
+int iswhite(char c);
+int isdelim(char c);
+
+
+/* Load a file into a buffer. */
+char* load_file(char *fname) {
+ FILE *fp;
+ char *p;
+ int size;
+
+ if(!(fp=fopen(fname, "rb"))) return 0;
+
+ // Get file size
+ fseek(fp, 0, SEEK_END);
+ size = ftell(fp);
+ p = (char*)malloc(size + 2);
+ fseek(fp, 0, SEEK_SET);
+
+ // Read file contents
+ fread(p, size, 1, fp);
+ fclose(fp);
+
+ /* null terminate the program */
+ if (p[size-1] != '\n') p[size++] = '\n';
+ p[size] = 0;
+
+ return p;
+}
+
+
+/* Find the start of the next line. */
+void find_eol()
+{
+ while(*prog_ip!='\n' && *prog_ip!='\0') ++prog_ip;
+ if(*prog_ip) prog_ip++;
+}
+
+/* Get a token. */
+int get_token()
+{
+
+ register char *temp;
+
+ token_type=0; tok=0;
+ temp=token;
+
+ if(*prog_ip=='\0') { /* end of file */
+ *token=0;
+ tok = FINISHED;
+ return(token_type=DELIMITER);
+ }
+
+ while(iswhite(*prog_ip)) ++prog_ip; /* skip over white space */
+
+ if(*prog_ip=='\r') { /* crlf */
+ ++prog_ip; ++prog_ip;
+ tok = EOL; *token='\r';
+ token[1]='\n'; token[2]=0;
+ return (token_type = DELIMITER);
+ }
+ if (*prog_ip=='\n') { /* lf (unix newline) */
+ ++prog_ip;
+ tok = EOL; *token='\n'; token[1] = 0;
+ return (token_type = DELIMITER);
+ }
+
+ if(strchr("+-*^/%=;(),><", *prog_ip)){ /* delimiter */
+ *temp=*prog_ip;
+ prog_ip++; /* advance to next position */
+ temp++;
+ *temp=0;
+ return (token_type=DELIMITER);
+ }
+
+ if(*prog_ip=='"') { /* quoted string */
+ prog_ip++;
+ while(*prog_ip!='"'&& *prog_ip!='\r' && *prog_ip!='\n') {
+ if (temp - token < TOK_LEN - 1) *temp++=*prog_ip;
+ prog_ip++;
+ }
+ if(*prog_ip=='\r' || *prog_ip=='\n') serror(1);
+ prog_ip++;*temp=0;
+ return(token_type=QUOTE);
+ }
+
+ if(isdigit(*prog_ip)) { /* number */
+ while(!isdelim(*prog_ip)) {
+ if (temp - token < TOK_LEN - 1) *temp++=*prog_ip;
+ prog_ip++;
+ }
+ *temp = '\0';
+ return(token_type = NUMBER);
+ }
+
+ if(isalpha(*prog_ip)) { /* var or command */
+ while(!isdelim(*prog_ip)) {
+ if (temp - token < TOK_LEN - 1) *temp++=*prog_ip;
+ prog_ip++;
+ }
+ token_type=STRING;
+ }
+
+ *temp = '\0';
+
+ /* see if a string is a command or a variable */
+ if(token_type==STRING) {
+ tok=look_up(token); /* convert to internal rep */
+ if(!tok) token_type = VARIABLE;
+ else token_type = COMMAND; /* is a command */
+ }
+ return token_type;
+}
+
+
+
+/* Return a token to input stream. */
+void putback()
+{
+
+ char *t;
+
+ t = token;
+ for(; *t; t++) prog_ip--;
+}
+
+/* Look up a a token's internal representation in the
+ token table.
+ */
+int look_up(char *s)
+{
+ register int i;
+ char *p;
+
+ /* convert to lowercase */
+ p = s;
+ while(*p){ *p = tolower(*p); p++; }
+
+ /* see if token is in table */
+ for(i=0; *table[i].command; i++)
+ if(!strcmp(table[i].command, s)) return table[i].tok;
+ return 0; /* unknown command */
+}
+
+/* Return true if c is a delimiter. */
+int isdelim(char c)
+{
+ if(strchr(" ;,+-<>/*%^=()", c) || c==9 || c=='\r' || c=='\n' || c==0)
+ return 1;
+ return 0;
+}
+
+/* Return 1 if c is space or tab. */
+int iswhite(char c)
+{
+ if(c==' ' || c=='\t') return 1;
+ else return 0;
+}
+
+
+
diff --git a/src/user/app/kbasic/main.c b/src/user/app/kbasic/main.c
new file mode 100644
index 0000000..1003a7b
--- /dev/null
+++ b/src/user/app/kbasic/main.c
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <readline.h>
+
+#include "basic.h"
+
+int main(int argc, char **argv) {
+ char *p_buf;
+
+ srand(0); // not very usefull...
+
+ readline_history hist;
+ hist.str = 0; hist.max = 10;
+
+ interp_name = argv[0];
+ init();
+
+ if(argc == 2) {
+ /* load the program to execute */
+ if(!(p_buf = load_file(argv[1]))) exit(1);
+
+ load_program(p_buf);
+ start(p_buf);
+ } else if (argc == 1) {
+ printf("KBASIC 0.1\n"
+ "Press ^D to quit interpreter.\n\n");
+
+ for (;;) {
+ printf("> ");
+ char *l = freadline(stdin, &hist);
+ if (l == NULL) break;
+
+ if (!strcmp(l, "exit")) {
+ free(l);
+ break;
+ }
+
+ prog_ip = l;
+ get_token();
+ if (token_type == NUMBER) { // label. insert line.
+ insert_line(l, atoi(token));
+ } else { // directly execute
+ start(l);
+ }
+ free(l);
+ }
+ } else {
+ printf("usage:\n\t%s <filename>\trun BASIC file\n", argv[0]);
+ printf("\n\t%s\t\t\tinteractive BASIC interpreter\n", argv[0]);
+ exit(1);
+ }
+
+ return 0;
+}
+
diff --git a/src/user/app/kbasic/pppg.bas b/src/user/app/kbasic/pppg.bas
new file mode 100644
index 0000000..32fc050
--- /dev/null
+++ b/src/user/app/kbasic/pppg.bas
@@ -0,0 +1,14 @@
+
+n = RND % 100
+e = 0
+
+20 input "Devinez le nombre: ", i
+e = e + 1
+if i > n then print "Trop grand !"
+if i < n then print "Trop petit !"
+if i = n then goto 42
+goto 20
+
+42 print "Bravo, vous avez trouvé en ", e, " essais!"
+end
+
diff --git a/src/user/app/kbasic/tables.bas b/src/user/app/kbasic/tables.bas
new file mode 100644
index 0000000..31e9ce3
--- /dev/null
+++ b/src/user/app/kbasic/tables.bas
@@ -0,0 +1,15 @@
+input "Taille de la table: ", k
+print "Table d'addition:"
+for i = 0 to k
+ for j = 0 to k
+ print i+j;
+ next
+ print
+next
+print "Table de multiplication:"
+for i = 1 to k
+ for j = 1 to k
+ print i * j;
+ next
+ print
+next
diff --git a/src/user/app/kbasic/var.c b/src/user/app/kbasic/var.c
new file mode 100644
index 0000000..a49ce61
--- /dev/null
+++ b/src/user/app/kbasic/var.c
@@ -0,0 +1,19 @@
+#include <ctype.h>
+
+#include "basic.h"
+
+int variables[26]= { /* 26 user variables, A-Z */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0
+};
+
+/* Find a pointer to the value of a variable. */
+int* find_var(char *s)
+{
+ if(!isalpha(*s)){
+ serror(4); /* not a variable */
+ return 0;
+ }
+ return variables + (toupper(*s)-'A');
+}
diff --git a/src/user/app/led/main.c b/src/user/app/led/main.c
index 5e73c59..dcf830d 100644
--- a/src/user/app/led/main.c
+++ b/src/user/app/led/main.c
@@ -33,7 +33,7 @@ void parse_range(char *k, int *l1, int *l2) {
}
}
-int main(char **args) {
+int main(int argc, char **args) {
int linecount;
char **lines;
int i, j;
@@ -53,7 +53,7 @@ int main(char **args) {
lines = malloc(1 * sizeof(char*));
lines[0] = 0;
} else if (info.type & FT_FILE) {
- FILE f = open(args[1], FM_READ);
+ int f = open(args[1], FM_READ);
char* buff = (char*)malloc(info.size);
read(f, 0, info.size, buff);
close(f);
@@ -95,7 +95,7 @@ int main(char **args) {
// run
while (lines) {
printf("[%d lines] ", linecount);
- char *s = freadline(term, &hist);
+ char *s = freadline(stdin, &hist);
if (strcmp(s, "q") == 0) {
break;
} else if (strcmp(s, "l") == 0) {
@@ -132,7 +132,7 @@ int main(char **args) {
}
// write buffer
- FILE f = open(args[1], FM_WRITE | FM_TRUNC | FM_CREATE | FT_FILE);
+ int f = open(args[1], FM_WRITE | FM_TRUNC | FM_CREATE | FT_FILE);
if (f > 0) {
write(f, 0, buffsz, buff);
close(f);
diff --git a/src/user/app/prime/main.c b/src/user/app/prime/main.c
index d3ebb7d..d9b60ab 100644
--- a/src/user/app/prime/main.c
+++ b/src/user/app/prime/main.c
@@ -8,7 +8,7 @@ int is_prime(int i) {
return 1;
}
-int main(char **args) {
+int main(int argc, char **args) {
int i;
for (i = 2; i < 1000000; i++) {
if (is_prime(i)) printf("%d\t", i);
diff --git a/src/user/app/test/main.c b/src/user/app/test/main.c
index 939a15a..3db24b3 100644
--- a/src/user/app/test/main.c
+++ b/src/user/app/test/main.c
@@ -39,7 +39,7 @@ void useless_thread(void* d) {
}
}
-int main(char** args) {
+int main(int argc, char** args) {
char**a;
if (args != 0) {
printk("(test) args");
diff --git a/src/user/app/yosh/Makefile b/src/user/app/yosh/Makefile
index bf55ce1..759531e 100644
--- a/src/user/app/yosh/Makefile
+++ b/src/user/app/yosh/Makefile
@@ -1,6 +1,6 @@
Obj = main.o
Out = yosh.elf
-include $(SrcPath)/user/app/fwik.make
+include $(SrcPath)/user/app/common.make
LDFLAGS += -Map yosh.map
diff --git a/src/user/app/yosh/main.c b/src/user/app/yosh/main.c
new file mode 100644
index 0000000..7c9b875
--- /dev/null
+++ b/src/user/app/yosh/main.c
@@ -0,0 +1,292 @@
+#include <tce/syscall.h>
+#include <tce/vfs.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <readline.h>
+
+char *cwd;
+
+void about() {
+ printf("Trivial/Computing Environment v0.1.4 - yosh 4.\n");
+}
+
+void help(char **args) {
+ if (!args[1]) {
+ printf("Available commands: about, help, exit, ls, cd, goto.\n");
+ } else if (!strcmp(args[1], "about")) {
+ printf("Usage:\tabout\nShows some info about yosh. Very usefull.\n");
+ } else if (!strcmp(args[1], "help")) {
+ printf("Usage:\thelp\n\thelp <command>\n");
+ printf("Shows some info about the command you want, or commands in general.\n");
+ } else if (!strcmp(args[1], "exit")) {
+ printf("Usage:\texit\n");
+ printf("Exits the shell.\nWill probably make your system panic if you only have a shell running.\n");
+ } else if (!strcmp(args[1], "cd")) {
+ printf("Usage:\tcd <location>\nGoes to the location specified.\n");
+ } else if (!strcmp(args[1], "ls")) {
+ printf("Usage:\tls\n\tls <location>...\nShows the content of the current/specified directory.\n");
+ } else if (!strcmp(args[1], "goto")) {
+ printf("Usage:\tgoto <vt name>\nSwitchs focus to specified virtual terminal.\n");
+ printf("Type `ls /.ui` to see available terminals.\n");
+ } else {
+ printf("No such command: %s\n", args[1]);
+ }
+}
+
+void cd(char **args) {
+ if (!args[1]) {
+ printf("Usage: cd <directory>\n");
+ }
+ if (!strcmp(args[1], ".")) return;
+
+ char* newcwd = path_cat(cwd, args[1], 1);
+
+ file_info f;
+ int r = stat(newcwd, &f);
+ if (r == E_NOT_FOUND) {
+ printf("No such file or directory.\n");
+ } else if (r != 0) {
+ printf("Error stating: %i\n", r);
+ } else if (!(f.type & FT_DIR)) {
+ printf("Not a directory.\n");
+ } else {
+ free(cwd);
+ cwd = newcwd;
+ return;
+ }
+ free(newcwd);
+}
+
+void ls_dir(int fd) {
+ char buf[256];
+ int pos = 0;
+
+ while (read(fd, pos++, 256, buf) > 0) {
+ if ((!strcmp(buf, ".")) || (!strcmp(buf, ".."))) continue;
+
+ printf(" %s", buf);
+
+ file_info info;
+ stat_relative(fd, buf, &info);
+ if (info.type & FT_DIR) printf("/");
+ printf(" \t");
+
+ if (info.type & FT_FILE) printf("file ");
+ if (info.type & FT_DIR) printf("dir ");
+ if (info.type & FT_SYMLINK) printf("symlink ");
+ if (info.type & FT_DEV) printf("dev ");
+ if (info.type & FT_TERMINAL) printf("term ");
+
+ printf("\t");
+ if (info.type & FT_TERMINAL) {
+ printf("%ix%i", info.size >> 16, info.size & 0xFFFF);
+ } else if ((info.type & FT_DEV) == 0) {
+ printf("%i", info.size);
+ }
+
+ printf("\n");
+ }
+}
+
+void ls(char **args) {
+ if (!args[1]) {
+ int fd = open(cwd, FM_READ);
+ if (fd > 0) {
+ ls_dir(fd);
+ close(fd);
+ } else {
+ printf(" Could not open for read (%d).\n", fd);
+ }
+ } else {
+ int i;
+ for (i = 1; args[i]; i++) {
+ printf("Contents of %s :\n", args[i]);
+ char *d = path_cat(cwd, args[i], 1);
+
+ file_info i;
+ int r = stat(d, &i);
+
+ if (r == E_NOT_FOUND) {
+ printf(" No such file or directory\n");
+ } else if (r != 0) {
+ printf(" Error stating: %i\n", r);
+ } else if (!(i.type & FT_DIR)) {
+ printf(" Not a directory.\n");
+ } else {
+ int fd = open(d, FM_READ);
+ if (fd > 0) {
+ ls_dir(fd);
+ close(fd);
+ } else {
+ printf(" Could not open for read (%d).\n", fd);
+ }
+ }
+ free(d);
+ }
+ }
+}
+
+void cat(char **args) {
+ int i;
+ for (i = 1; args[i]; i++) {
+ char *d = path_cat(cwd, args[i], 0);
+ file_info info;
+ int e = stat(d, &info);
+ if (e == E_NOT_FOUND) {
+ printf("No such file: %s\n", d);
+ } else if (e < 0) {
+ printf("Error stating %s : %i\n", d, e);
+ } else if ((info.type & FT_FILE) == 0) {
+ printf("Not a file: %s\n", d);
+ } else {
+ int ff = open(d, 0);
+ char* buff = (char*)malloc(info.size);
+ read(ff, 0, info.size, buff);
+ close(ff);
+ write(term.fd, 0, info.size, buff);
+ free(buff);
+ }
+ free(d);
+ }
+}
+
+void t_goto(char **args) {
+ if (!args[1]) {
+ printf("Usage: goto <vt_name>\n");
+ return;
+ }
+ char *p = path_cat("/.ui/", args[1], 0);
+ int i;
+ if ((i = link(p, "/.dev/vgatxt", LM_OUTPUT_TO)) == 0) {
+ link("/.dev/ps2kbd", p, LM_OUTPUT_TO);
+ } else {
+ printf("Error %i\n", i);
+ }
+ free(p);
+}
+
+int main(int argc, char **sh_args) {
+ about();
+
+ cwd = strdup("/");
+
+ char *path = path_cat(sh_args[0], "..", 1);
+
+ int bg_pr[128], bg_pr_c = 0;
+
+ readline_history hist;
+ hist.str = 0; hist.max = 10;
+
+ while (1) {
+ // check for background processes that may have finished
+ int p = 0;
+ while (p < bg_pr_c) {
+ int ret = waitpid(bg_pr[p], 0);
+ if (ret != E_NOT_FINISHED) {
+ printf("(yosh) child (pid %i) exited with status %i\n", bg_pr[p], ret);
+ bg_pr_c--;
+ bg_pr[p] = bg_pr[bg_pr_c];
+ } else {
+ p++;
+ }
+ }
+
+ // show prompt
+ printf("\x1b[33m %s \x1b[1m", cwd);
+ char *s = freadline(stdin, &hist);
+ printf("\x1b[0m");
+ if (s == NULL) break;
+ if (strlen(s) == 0) continue;
+
+ char *a_c = strdup(s); // duplicate because we're gonna add '\0'es
+
+ char *c_args[16];
+ char *start = a_c, *pos = a_c;
+ int argc = 0;
+ while (*pos) {
+ if (*pos == ' ') {
+ if (pos == start) {
+ start++;
+ } else {
+ *pos = 0;
+ c_args[argc] = start;
+ argc++;
+ start = pos + 1;
+ if (argc == 14) {
+ break;
+ }
+ }
+ }
+ pos++;
+ }
+ c_args[argc++] = start;
+ c_args[argc] = 0;
+
+ if (!strcmp(c_args[0], "about")) {
+ about();
+ } else if (!strcmp(c_args[0], "help")) {
+ help(c_args);
+ } else if (!strcmp(c_args[0], "exit")) {
+ printf("Exiting the shell. See you later!\n");
+ break;
+ } else if (!strcmp(c_args[0], "cd")) {
+ cd(c_args);
+ } else if (!strcmp(c_args[0], "ls")) {
+ ls(c_args);
+ } else if (!strcmp(c_args[0], "goto")) {
+ t_goto(c_args);
+ } else if (!strcmp(c_args[0], "cat")) {
+ cat(c_args);
+ } else {
+ char **first_arg = c_args;
+
+ char *term_s = NULL;
+ int vt_fd = term.fd;
+
+ if (!strcmp(c_args[0], "on")) {
+ if (!c_args[1] || !c_args[2]) {
+ printf("Usage:\ton <vt> <command>\n");
+ continue;
+ }
+ term_s = path_cat("/.ui/", c_args[1], 1);
+ vt_fd = open(term_s, 0);
+ if (vt_fd < 0 || vt_fd == term.fd) {
+ printf("Error: cannot open terminal %s (%i)\n", term_s, vt_fd);
+ continue;
+ }
+ first_arg += 2;
+ }
+
+ char *c;
+ if (strchr(*first_arg, '/')) {
+ c = path_cat(cwd, *first_arg, 0);
+ } else {
+ c = path_cat(path, *first_arg, 0);
+ }
+ first_arg++;
+
+ int pid = run(c, (const char**)first_arg, vt_fd);
+ if (pid <= 0) {
+ if (pid == E_NOT_FOUND) {
+ printf("Error: no such file %s\n", c);
+ } else {
+ printf("Error %i\n", pid);
+ }
+ } else {
+ if (term_s == NULL) {
+ int ret = waitpid(pid, 1);
+ printf("(yosh) child (pid %i) exited with status %i\n", pid, ret);
+ } else {
+ printf("(yosh) running on terminal %s, pid:%i\n", term_s, pid);
+ bg_pr[bg_pr_c++] = pid;
+ }
+ }
+ free(c);
+ if (term_s) free(term_s);
+ }
+
+ free(a_c);
+ }
+
+ return 0;
+}
diff --git a/src/user/app/yosh/main.cpp b/src/user/app/yosh/main.cpp
deleted file mode 100644
index 160e728..0000000
--- a/src/user/app/yosh/main.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-#include <tce/syscall.h>
-#include <tce/vfs.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <readline.h>
-#include <IO/IOStream.h>
-#include <IO/Dir.h>
-
-Dir *cwd_f;
-String cwd;
-
-void about() {
- stdio << "Trivial/Computing Environment v0.1.0 - yosh 3.\n";
-}
-
-void help(String *args) {
- if (!args[1]) {
- stdio << "Available commands: about, help, exit, ls, cd, goto.\n";
- } else if (args[1] == "about") {
- stdio << "Usage:\tabout\nShows some info about yosh. Very usefull.\n";
- } else if (args[1] == "help") {
- stdio << "Usage:\thelp\n\thelp <command>\n"
- << "Shows some info about the command you want, or commands in general.\n";
- } else if (args[1] == "exit") {
- stdio << "Usage:\texit\n"
- << "Exits the shell.\nWill probably make your system panic if you only have a shell running.\n";
- } else if (args[1] == "cd") {
- stdio << "Usage:\tcd <location>\nGoes to the location specified.\n";
- } else if (args[1] == "ls") {
- stdio << "Usage:\tls\n\tls <location>...\nShows the content of the current/specified directory.\n";
- } else if (args[1] == "goto") {
- stdio << "Usage:\tgoto <vt name>\nSwitchs focus to specified virtual terminal.\n"
- << "Type `ls /.ui` to see available terminals.\n";
- } else {
- stdio.printf("No such command: %s\n", args[1].c_str());
- }
-}
-
-void cd(String *args) {
- if (!args[1]) {
- stdio << "Usage: cd <directory>\n";
- }
- if (args[1] == ".") return;
-
- String newcwd = path_cat(cwd, args[1]);
-
- Dir *newdir = new Dir(newcwd.c_str(), 0);
- if (newdir->error == E_NOT_FOUND) {
- stdio << "No such file or directory.\n";
- } else if (newdir->error == E_INVALID_TYPE) {
- stdio << "Not a directory.\n";
- } else if (newdir->error != 0) {
- stdio.printf("Error stating: %i\n", newdir->error);
- } else {
- cwd_f->close();
- cwd = newcwd;
- cwd_f = newdir;
- }
-}
-
-void ls_dir(Dir *d) {
- if (d->error != 0) {
- return;
- }
- d->pos = 0;
- for (String name = d->read_ent(); name; name = d->read_ent()) {
- if (name == "." || name == "..") continue;
-
- stdio.printf(" %s", name.c_str());
-
- Node child(d->fd, name.c_str(), 0);
-
- if (child.info.type & FT_DIR) stdio << "/";
- stdio << " \t";
-
- if (child.info.type & FT_FILE) stdio << "file ";
- if (child.info.type & FT_DIR) stdio << "dir ";
- if (child.info.type & FT_SYMLINK) stdio << "symlink ";
- if (child.info.type & FT_DEV) stdio << "dev ";
- if (child.info.type & FT_TERMINAL) stdio << "term ";
-
- stdio << "\t";
- if (child.info.type & FT_TERMINAL) {
- stdio.printf("%ix%i", child.info.size >> 16, child.info.size & 0xFFFF);
- } else if ((child.info.type & FT_DEV) == 0) {
- stdio.printf("%i", child.info.size);
- }
-
- stdio << "\n";
- }
-}
-
-void ls(String *args) {
- if (!args[1]) {
- ls_dir(cwd_f);
- } else {
- int i;
- for (i = 1; args[i]; i++) {
- stdio.printf("Contents of %s :\n", args[i].c_str());
- String d = path_cat(cwd, args[i].c_str());
- Dir dir(d.c_str(), 0);
- if (dir.error == E_NOT_FOUND) {
- stdio << " No such file or directory\n";
- } else if (dir.error == E_INVALID_TYPE) {
- stdio.printf(" Not a directory.\n");
- } else if (dir.error < 0) {
- stdio.printf(" Error stating: %i\n", dir.error);
- } else {
- ls_dir(&dir);
- dir.close();
- }
- }
- }
-}
-
-void cat(String *args) {
- int i;
- for (i = 1; args[i]; i++) {
- String d = path_cat(cwd, args[i], false);
- file_info info;
- int e = libc::stat(d.c_str(), &info);
- if (e == E_NOT_FOUND) {
- stdio.printf("No such file: %s\n", d.c_str());
- } else if (e < 0) {
- stdio.printf("Error stating %s : %i\n", d.c_str(), e);
- } else if ((info.type & FT_FILE) == 0) {
- stdio.printf("Not a file: %s\n", d.c_str());
- } else {
- FILE ff = libc::open(d.c_str(), 0);
- char* buff = (char*)malloc(info.size);
- libc::read(ff, 0, info.size, buff);
- libc::close(ff);
- libc::write(stdio.term->fd, 0, info.size, buff);
- free(buff);
- }
- }
-}
-
-void t_goto(String *args) {
- if (!args[1]) {
- stdio << "Usage: goto <vt_name>\n";
- return;
- }
- String p = path_cat("/.ui/", args[1], false);
- int i;
- if ((i = libc::link(p.c_str(), "/.dev/vgatxt", LM_OUTPUT_TO)) == 0) {
- libc::link("/.dev/ps2kbd", p.c_str(), LM_OUTPUT_TO);
- } else {
- stdio.printf("Error %i\n", i);
- }
-}
-
-int Main(String *sh_args) {
- about();
-
- cwd = "/";
- cwd_f = new Dir("/", 0);
-
- String path = path_cat(sh_args[0], "..");
-
- int bg_pr[128], bg_pr_c = 0;
-
- Term *term = stdio.term;
- if (term == 0) {
- stdio << "Error: no terminal...\n";
- return -1;
- }
-
- while (1) {
- // check for background processes that may have finished
- int p = 0;
- while (p < bg_pr_c) {
- int ret = libc::waitpid(bg_pr[p], 0);
- if (ret != E_NOT_FINISHED) {
- stdio.printf("(yosh) child (pid %i) exited with status %i\n", bg_pr[p], ret);
- bg_pr_c--;
- bg_pr[p] = bg_pr[bg_pr_c];
- } else {
- p++;
- }
- }
-
- // show prompt
- stdio.printf("\x1b[33m %s \x1b[1m", cwd.c_str());
- String s = term->readline();
- stdio.printf("\x1b[0m");
- if (s.size() == 0) continue;
-
- String c_args[16];
- int argc = 0, start = 0;
- for (int i = 0; i < s.size(); i++) {
- if (s[i] == ' ') {
- if (start == i) {
- start++;
- } else {
- c_args[argc] = s.substr(start, i - start);
- argc++;
- start = i + 1;
- if (argc == 15) {
- break;
- }
- }
- }
- }
- c_args[argc++] = s.substr(start, s.size() - start);
-
- if (c_args[0] == "about") {
- about();
- } else if (c_args[0] == "help") {
- help(c_args);
- } else if (c_args[0] == "exit") {
- stdio << "Exiting the shell. See you later!\n";
- break;
- } else if (c_args[0] == "cd") {
- cd(c_args);
- } else if (c_args[0] == "ls") {
- ls(c_args);
- } else if (c_args[0] == "goto") {
- t_goto(c_args);
- } else if (c_args[0] == "cat") {
- cat(c_args);
- } else {
- FILE vt = term->fd;
- String *first_arg = c_args ;
- String t;
-
- if (c_args[0] == "on") {
- if (!c_args[1] || !c_args[2]) {
- stdio.printf("Usage:\ton <vt> <command>\n");
- continue;
- }
- t = path_cat("/.ui/", c_args[1], false);
- vt = libc::open(t.c_str(), 0);
- if (vt < 0 || vt == term->fd) {
- stdio.printf("Error: cannot open terminal %s (%i)\n", t.c_str(), vt);
- continue;
- }
- first_arg += 2;
- }
-
- String c;
- if (libc::strchr(first_arg->c_str(), '/')) {
- c = path_cat(cwd, *first_arg, false);
- } else {
- c = path_cat(path, *first_arg, false);
- }
- first_arg++;
- const char *run_args[15] = {0};
- for (int i = 0; first_arg[i]; i++) run_args[i] = first_arg[i].c_str();
-
- int pid = libc::run(c.c_str(), run_args, vt);
- if (pid <= 0) {
- if (pid == E_NOT_FOUND) {
- stdio.printf("Error: no such file %s\n", c.c_str());
- } else {
- stdio.printf("Error %i\n", pid);
- }
- } else {
- if (vt == term->fd) {
- int ret = libc::waitpid(pid, 1);
- stdio.printf("(yosh) child (pid %i) exited with status %i\n", pid, ret);
- } else {
- stdio.printf("(yosh) running on terminal %s, pid:%i\n", t.c_str(), pid);
- bg_pr[bg_pr_c++] = pid;
- }
- }
- }
- }
-
- return 0;
-}