Updated README.md

This commit is contained in:
Jacob Signorovitch 2024-12-14 20:35:36 -05:00
parent feae5d560a
commit 8763fa35dd
9 changed files with 59 additions and 48 deletions

View File

@ -1,12 +1,13 @@
--- ---
BasedOnStyle: LLVM
AlignConsecutiveShortCaseStatements: AlignConsecutiveShortCaseStatements:
Enabled: true Enabled: true
AcrossEmptyLines: true AcrossEmptyLines: true
AcrossComments: true AcrossComments: true
IndentCaseLabels: true
AllowShortBlocksOnASingleLine: Always AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: true AllowShortCaseLabelsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: AllIfsAndElse AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AllowShortLoopsOnASingleLine: true AllowShortLoopsOnASingleLine: true
IndentWidth: 4 IndentWidth: 4
PointerAlignment: Left PointerAlignment: Left
AlignAfterOpenBracket: BlockIndent

View File

@ -1,4 +1,4 @@
# SCL: Simple Calculator Language # SCL: Simple CAS Language
## Syntax ## Syntax
@ -12,16 +12,24 @@ As one would expect, you can evaluate simple infix expressions:
You can also define your own functions: You can also define your own functions:
```scl ```scl
> f(x) 2x > f(x) = 2x
> f(2) > f(2)
= 4 = 4
``` ```
Symbolic algebra is done in the following manner:
```scl
> f(x) = e^x
> diff(f, x:sym, 2)
= e^x
```
SCL will dynamically decide on types, but you can state them explicitly as SCL will dynamically decide on types, but you can state them explicitly as
well: well:
```scl ```scl
> f(x:int) 2x > f(x:int) = 2x
> f(2.2) > f(2.2)
! f(x:int): x must be of type int. ! f(x:int): x must be of type int.
``` ```
@ -32,6 +40,5 @@ Variables can be defined, with several attributes:
> a = 1 // Interpret type automatically. > a = 1 // Interpret type automatically.
> b:int = 1 // Must be int. > b:int = 1 // Must be int.
> c:const:int = 1 // Constant: value can never change. > c:const:int = 1 // Constant: value can never change.
> d:lazy = (1 + 1) // Interpreter will wait as long as possible before > x:sym // Treated symbolicaly.
// evaluating.
``` ```

View File

@ -24,9 +24,10 @@ void ast_destroy(AST* ast) {
if (!ast) return; if (!ast) return;
switch (ast->type) { switch (ast->type) {
case AST_TYPE_NUM: ast_num_data_destroy(ast->data); break; case AST_TYPE_NUM: ast_num_data_destroy(ast->data); break;
case AST_TYPE_CALL: ast_call_data_destroy(ast->data); break; case AST_TYPE_CALL: ast_call_data_destroy(ast->data); break;
default: log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX); default:
log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX);
} }
} }
@ -39,11 +40,11 @@ void ast_print_i(AST* ast, int i) {
INDENT_FIELD("type", "%s", asttype_names[ast->type]); INDENT_FIELD("type", "%s", asttype_names[ast->type]);
INDENT_FIELD_EXT_NONL_START("data"); INDENT_FIELD_EXT_NONL_START("data");
switch (ast->type) { switch (ast->type) {
case AST_TYPE_NUM: case AST_TYPE_NUM:
printf("%s %lf\n", INDENT_spacing->buf, *(ASTNumData*)ast->data); printf("%s %lf\n", INDENT_spacing->buf, *(ASTNumData*)ast->data);
break; break;
case AST_TYPE_CALL: ast_call_print(ast->data, i + 2); break; case AST_TYPE_CALL: ast_call_print(ast->data, i + 2); break;
default: exit(1); default: exit(1);
} }
INDENT_FIELD_NONL_END; INDENT_FIELD_NONL_END;
INDENT_END; INDENT_END;

View File

@ -25,8 +25,10 @@ void dstr_append(Dstr* dest, char* src, size_t ln) {
// Double the buffer size when overflown. // Double the buffer size when overflown.
dest->bufsz *= 2; dest->bufsz *= 2;
dest->buf = realloc(dest->buf, dest->bufsz); dest->buf = realloc(dest->buf, dest->bufsz);
log_dbgf("dstr @ %p doubled from %ld to %ld", dest, dest->bufsz / 2, log_dbgf(
dest->bufsz); "dstr @ %p doubled from %ld to %ld", dest, dest->bufsz / 2,
dest->bufsz
);
} }
// Overwrites the \0 at the end of the string, keeps the null from the given // Overwrites the \0 at the end of the string, keeps the null from the given
@ -40,8 +42,10 @@ void dstr_appendch(Dstr* dest, char ch) {
// Double the buffer size when overflown. // Double the buffer size when overflown.
dest->bufsz *= 2; dest->bufsz *= 2;
dest->buf = realloc(dest->buf, dest->bufsz); dest->buf = realloc(dest->buf, dest->bufsz);
log_dbgf("dstr @ %p doubled from %ld to %ld", dest, dest->bufsz / 2, log_dbgf(
dest->bufsz); "dstr @ %p doubled from %ld to %ld", dest, dest->bufsz / 2,
dest->bufsz
);
} }
// Overwrites the preexisting null terminator, and adds one of its own. // Overwrites the preexisting null terminator, and adds one of its own.

View File

@ -11,11 +11,11 @@ ASTNumData exec_expr(AST* ast) {
ast_print(ast); ast_print(ast);
log_dbg("Started execution."); log_dbg("Started execution.");
switch (ast->type) { switch (ast->type) {
case AST_TYPE_CALL: return exec_call(ast); case AST_TYPE_CALL: return exec_call(ast);
case AST_TYPE_NUM: case AST_TYPE_NUM:
exec_print(*(ASTNumData*)ast->data); exec_print(*(ASTNumData*)ast->data);
return *(ASTNumData*)ast->data; return *(ASTNumData*)ast->data;
default: printf("what\n"); default: printf("what\n");
} }
} }

View File

@ -4,14 +4,14 @@
#include <assert.h> #include <assert.h>
#ifdef __has_include #ifdef __has_include
#if __has_include("../../build/grammars/grammar.tab.h") #if __has_include("../../build/grammars/grammar.tab.h")
#include "../../build/grammars/grammar.tab.h" #include "../../build/grammars/grammar.tab.h"
#else
#warn "Build resources not present!"
#endif
#else #else
#warn "Not sure whether build-time resources are present." #warn "Build resources not present!"
#include "../../build/grammars/grammar.tab.h" #endif
#else
#warn "Not sure whether build-time resources are present."
#include "../../build/grammars/grammar.tab.h"
#endif #endif
extern YYSTYPE yylval; extern YYSTYPE yylval;

View File

@ -1,7 +1,7 @@
#include <ctype.h> #include <ctype.h>
#include <limits.h> #include <limits.h>
#include <stdio.h>
#include <math.h> #include <math.h>
#include <stdio.h>
#include "include/lexer.h" #include "include/lexer.h"
@ -24,13 +24,14 @@ double acc_float(int c) {
inp++; inp++;
} }
if (*inp == '.') { if (*inp == '.') {
inp++; inp++;
while (isdigit(*inp)) { while (isdigit(*inp)) {
// TODO: // TODO:
// Accumulate as int, divide once at end. // Accumulate as int, divide once at end.
// value = value + (((double)(*inp - '0'))/pow(10.0l, (double)(inp-oinp))); // Accumulate value. // value = value + (((double)(*inp - '0'))/pow(10.0l,
// (double)(inp-oinp))); // Accumulate value.
value = value * 10 + (*inp - '0'); // Accumulate value. value = value * 10 + (*inp - '0'); // Accumulate value.
dplaces++; dplaces++;
inp++; inp++;
@ -62,9 +63,9 @@ int yylex() {
} }
switch (c) { switch (c) {
case '+': return PLUS; case '+': return PLUS;
case '\n': return NL; case '\n': return NL;
default: return CALL; default: return CALL;
} }
fprintf(stderr, "Unexpected character: %c\n", c); fprintf(stderr, "Unexpected character: %c\n", c);

View File

@ -2,9 +2,9 @@
#include "include/ast.h" #include "include/ast.h"
#include "include/dstr.h" #include "include/dstr.h"
#include "include/exec.h"
#include "include/lexer.h" #include "include/lexer.h"
#include "include/util.h" #include "include/util.h"
#include "include/exec.h"
#include "../build/grammars/grammar.tab.h" #include "../build/grammars/grammar.tab.h"
@ -29,10 +29,9 @@ int main(int argc, char** argv) {
do { do {
c = getc(stdin); c = getc(stdin);
switch (c) { switch (c) {
case EOF: dstr_destroy(ln); goto lnskip; case EOF: dstr_destroy(ln); goto lnskip;
case '\n': goto lnend; case '\n': goto lnend;
default: dstr_appendch(ln, c); log_dbgf("cchar: %c", c);
default: dstr_appendch(ln, c); log_dbgf("cchar: %c", c);
} }
} while (1); } while (1);
@ -41,14 +40,12 @@ int main(int argc, char** argv) {
log_dbgf("cline: %s", ln->buf); log_dbgf("cline: %s", ln->buf);
if (ln->ln > 0) { if (ln->ln > 0) {
// I hope it's null-terminated. // I hope to god it's null-terminated.
inp = ln->buf; inp = ln->buf;
if (yyparse() == 0) if (yyparse() == 0) printf("Parsed successfully!\n");
printf("Parsed successfully!\n"); else printf("Parse error.\n");
else
printf("Parse error.\n");
//exec_expr(root); // exec_expr(root);
ast_print(root); ast_print(root);
} }

View File

@ -2,8 +2,8 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "include/util.h"
#include "include/stack.h" #include "include/stack.h"
#include "include/util.h"
Stack* stack_init() { Stack* stack_init() {
talloc(Stack, stack); talloc(Stack, stack);