initial commit

This commit is contained in:
Matthieu Bessat 2022-04-20 20:10:00 +02:00
commit 1f4f58b3fb
11 changed files with 313 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
./main

6
Makefile Normal file
View file

@ -0,0 +1,6 @@
WERROR?=
CFLAGS=-Wall -Wextra $(WERROR) -pedantic -I.
CXXFLAGS_WITHOUT_PKGS=$(CFLAGS) -fno-exceptions -Wno-missing-braces -Wswitch-enum -lm
build:
gcc src/* -o ./main ${CXXFLAGS_WITHOUT_PKGS}

82
README.md Normal file
View file

@ -0,0 +1,82 @@
# Simple BASIC language implementation
The goal of this project is to create a simple implementation of a BASIC-like language.
No need to do complex thing, just to create a simple interpreted language that can be used to do some arithmetics
and create for ex a number guessing game.
## Technology
We will create our own regex engine
## Syntax
One instruction set per line
Instruction sets avalaibles:
### Commentary
can only use single line comments with `#`
```
# this is a comment
```
### Expression evaluation
can only operate on integer
function calls: func(arg_a, arg_b)
operators: +, *, /
booleans operators: not, and, or,
### function definition
```
function {NAME}
begin
...
end
```
### Set a variable
```
set {VARNAME} to {EXPRESSION}
```
### Conditional structure
```
if {EXPRESSION} then
begin
...
end
```
### Conditional loop
```
while {EXPRESSION} do
begin
...
end
```
### Unconditional loop
```
repeat {EXPRESSION THAT EVALUATE TO INT}
begin
end
```
### std functions
```
put_stdout()
take_stdin()
int_of_string()
random_int(min, max)
```

1
examples/basic_1.basic Normal file
View file

@ -0,0 +1 @@
PRINT 1

1
examples/basic_2.basic Normal file
View file

@ -0,0 +1 @@
PRINT (1+2)

5
examples/calc_1.basic Normal file
View file

@ -0,0 +1,5 @@
LET A BE 0
WHILE NOT A DO
PRINT A
LET A BE A+1
ENDWHILE

View file

@ -0,0 +1 @@
PRINT "Hello World"

BIN
main Executable file

Binary file not shown.

193
src/main.c Normal file
View file

@ -0,0 +1,193 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "./stack.h"
struct IntParsingResult {
bool hasError;
int value;
};
bool is_operator(char candidate) {
return (
candidate == '*' ||
candidate == '+'
);
}
bool is_char_numeral(char candidate) {
int n = (int) candidate;
return n >= 48 && n <= 57;
}
int integer_pow(int base, int exponent)
{
if (exponent == 0) return 1;
int r = 1;
int multiplier = base;
while (exponent) {
// if exponent is even
if (exponent & 1) {
r *= multiplier;
}
multiplier *= multiplier;
exponent >>= 1; // divide by two the exponent
}
return r;
}
int parse_clean_positive_integer(int inputStrLen, char* inputStr, int* result) {
/**
Parse an integer that is just a continus stream of decimal numbers
without any negative sign
**/
int i = 0;
int value = 0;
while (inputStr[i] != 0) {
if (!is_char_numeral(inputStr[i])) {
return 1;
}
int numeralIndex = (int) inputStr[i];
value += (
integer_pow(10, inputStrLen-(i+1)) *
(numeralIndex & 0b001111)
);
i++;
}
*result = value;
return 0;
}
int parse_int(char* inputStr, int* result) {
int i = 0;
char cleanStr[sizeof(inputStr)];
int cleanStrLen = 0;
int signIndex = -1;
while (inputStr[i] != 0) {
if (
!is_char_numeral(inputStr[i]) &&
inputStr[i] != '-' &&
inputStr[i] != ' ' &&
inputStr[i] != '_'
) {
// we've encounter a unexpected char
return 1;
}
if (signIndex >= 0 && inputStr[i] == '-') {
// we'v encounter a sign but we already have one
return 1;
}
if (signIndex == -1 && inputStr[i] == '-') {
signIndex = i;
}
if (is_char_numeral(inputStr[i])) {
cleanStr[cleanStrLen] = inputStr[i];
cleanStrLen++;
}
i++;
}
printf("clean str: %s \n", cleanStr);
parse_clean_positive_integer(cleanStrLen, cleanStr, result);
if (signIndex >= 0) {
*result *= -1;
}
return 0;
}
int evaluate(char *inputStr) {
int i = 0;
int leftOperand = 0;
int len = strlen(inputStr);
// we want first to parse the expression and create a stack
// for 4*81 : ["4", "*", "81"]
// for -4*(5+42) : ["-4", "*", "(", "5", "+", "42", ")"]
// as a matter of fact, this is a partition
// so we can treat that as a list of tuple (start,finish)
int partitionStartPos[len];
int partitionStopPos[len];
char buff[len];
int buffPtr = 0;
int partitionPtr = 0;
int lastStartPos = 0;
while (inputStr[i] != 0) {
if (
is_operator(inputStr[i]) ||
inputStr[i] == '(' ||
inputStr[i] == ')'
) {
if (lastStartPos != i) {
partitionStartPos[partitionPtr] = lastStartPos;
partitionStopPos[partitionPtr] = i;
partitionPtr++;
}
partitionStartPos[partitionPtr] = i;
partitionStopPos[partitionPtr] = i+1;
partitionPtr++;
lastStartPos = i+1;
i++;
continue;
}
i++;
}
if (lastStartPos != i) {
partitionStartPos[partitionPtr] = lastStartPos;
partitionStopPos[partitionPtr] = i;
partitionPtr++;
}
// display the partition
printf("partitionPtr: %d \n", partitionPtr);
for (int j = 0; j < partitionPtr; j++) {
printf("start %d ", partitionStartPos[j]);
printf("stop %d ", partitionStopPos[j]);
int len = partitionStopPos[j] - partitionStartPos[j];
char buff[sizeof(inputStr)];
for (int z = 0; z < sizeof(inputStr); z++) {
if (z < len) {
buff[z] = inputStr[partitionStartPos[j]+z];
}
if (z == len) {
buff[z] = 0;
}
}
printf("content %s \n", buff);
}
return 0;
}
//int create_stack(int a, int b)
int main () {
char *inputStr = "4732*(-5851+55)+899";
// int i = 0;
// while (inputStr[i] != 0) {
// printf("%d : '%c' \n", i, inputStr[i]);
// i++;
// }
// int parsedValue = 0;
// if (parse_int("-999", &parsedValue) > 0) {
// printf("Error parsing int \n");
// }
// printf("Value of int %d \n", parsedValue);
// read the file
//
printf("result is: %d \n", evaluate(inputStr));
}

14
src/stack.c Normal file
View file

@ -0,0 +1,14 @@
#include "./stack.h"
#define STACK_LEN = 255
struct IntStack {
int end_pos;
int data[STACK_LEN];
}
int stack_create(int a, int b)
{
return (a+b);
}

9
src/stack.h Normal file
View file

@ -0,0 +1,9 @@
#ifndef STACK_H_
#define STACK_H_
#define SOME_CST_A 42
int stack_create(int a, int b);
#endif