Initial commit :3
This commit is contained in:
		
						commit
						015ec69720
					
				
							
								
								
									
										192
									
								
								.clang-format
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								.clang-format
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,192 @@
 | 
			
		||||
---
 | 
			
		||||
Language:        Cpp
 | 
			
		||||
# BasedOnStyle:  Microsoft
 | 
			
		||||
AccessModifierOffset: -2
 | 
			
		||||
AlignAfterOpenBracket: Align
 | 
			
		||||
AlignArrayOfStructures: None
 | 
			
		||||
AlignConsecutiveMacros: None
 | 
			
		||||
AlignConsecutiveAssignments: None
 | 
			
		||||
AlignConsecutiveBitFields: None
 | 
			
		||||
AlignConsecutiveDeclarations: None
 | 
			
		||||
AlignEscapedNewlines: Right
 | 
			
		||||
AlignOperands:   Align
 | 
			
		||||
AlignTrailingComments: true
 | 
			
		||||
AllowAllArgumentsOnNextLine: true
 | 
			
		||||
AllowAllParametersOfDeclarationOnNextLine: true
 | 
			
		||||
AllowShortEnumsOnASingleLine: false
 | 
			
		||||
AllowShortBlocksOnASingleLine: Never
 | 
			
		||||
AllowShortCaseLabelsOnASingleLine: false
 | 
			
		||||
AllowShortFunctionsOnASingleLine: None
 | 
			
		||||
AllowShortLambdasOnASingleLine: All
 | 
			
		||||
AllowShortIfStatementsOnASingleLine: Never
 | 
			
		||||
AllowShortLoopsOnASingleLine: false
 | 
			
		||||
AlwaysBreakAfterDefinitionReturnType: None
 | 
			
		||||
AlwaysBreakAfterReturnType: None
 | 
			
		||||
AlwaysBreakBeforeMultilineStrings: false
 | 
			
		||||
AlwaysBreakTemplateDeclarations: MultiLine
 | 
			
		||||
AttributeMacros:
 | 
			
		||||
  - __capability
 | 
			
		||||
BinPackArguments: true
 | 
			
		||||
BinPackParameters: true
 | 
			
		||||
BraceWrapping:
 | 
			
		||||
  AfterCaseLabel:  false
 | 
			
		||||
  AfterClass:      true
 | 
			
		||||
  AfterControlStatement: Always
 | 
			
		||||
  AfterEnum:       true
 | 
			
		||||
  AfterFunction:   true
 | 
			
		||||
  AfterNamespace:  true
 | 
			
		||||
  AfterObjCDeclaration: true
 | 
			
		||||
  AfterStruct:     true
 | 
			
		||||
  AfterUnion:      false
 | 
			
		||||
  AfterExternBlock: true
 | 
			
		||||
  BeforeCatch:     true
 | 
			
		||||
  BeforeElse:      true
 | 
			
		||||
  BeforeLambdaBody: false
 | 
			
		||||
  BeforeWhile:     false
 | 
			
		||||
  IndentBraces:    false
 | 
			
		||||
  SplitEmptyFunction: true
 | 
			
		||||
  SplitEmptyRecord: true
 | 
			
		||||
  SplitEmptyNamespace: true
 | 
			
		||||
BreakBeforeBinaryOperators: None
 | 
			
		||||
BreakBeforeConceptDeclarations: true
 | 
			
		||||
BreakBeforeBraces: Custom
 | 
			
		||||
BreakBeforeInheritanceComma: false
 | 
			
		||||
BreakInheritanceList: BeforeColon
 | 
			
		||||
BreakBeforeTernaryOperators: true
 | 
			
		||||
BreakConstructorInitializersBeforeComma: false
 | 
			
		||||
BreakConstructorInitializers: BeforeColon
 | 
			
		||||
BreakAfterJavaFieldAnnotations: false
 | 
			
		||||
BreakStringLiterals: true
 | 
			
		||||
ColumnLimit:     120
 | 
			
		||||
CommentPragmas:  '^ IWYU pragma:'
 | 
			
		||||
QualifierAlignment: Leave
 | 
			
		||||
CompactNamespaces: false
 | 
			
		||||
ConstructorInitializerIndentWidth: 4
 | 
			
		||||
ContinuationIndentWidth: 4
 | 
			
		||||
Cpp11BracedListStyle: true
 | 
			
		||||
DeriveLineEnding: true
 | 
			
		||||
DerivePointerAlignment: false
 | 
			
		||||
DisableFormat:   false
 | 
			
		||||
EmptyLineAfterAccessModifier: Never
 | 
			
		||||
EmptyLineBeforeAccessModifier: LogicalBlock
 | 
			
		||||
ExperimentalAutoDetectBinPacking: false
 | 
			
		||||
PackConstructorInitializers: BinPack
 | 
			
		||||
BasedOnStyle:    ''
 | 
			
		||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
 | 
			
		||||
AllowAllConstructorInitializersOnNextLine: true
 | 
			
		||||
FixNamespaceComments: true
 | 
			
		||||
ForEachMacros:
 | 
			
		||||
  - foreach
 | 
			
		||||
  - Q_FOREACH
 | 
			
		||||
  - BOOST_FOREACH
 | 
			
		||||
IfMacros:
 | 
			
		||||
  - KJ_IF_MAYBE
 | 
			
		||||
IncludeBlocks:   Preserve
 | 
			
		||||
IncludeCategories:
 | 
			
		||||
  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
 | 
			
		||||
    Priority:        2
 | 
			
		||||
    SortPriority:    0
 | 
			
		||||
    CaseSensitive:   false
 | 
			
		||||
  - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
 | 
			
		||||
    Priority:        3
 | 
			
		||||
    SortPriority:    0
 | 
			
		||||
    CaseSensitive:   false
 | 
			
		||||
  - Regex:           '.*'
 | 
			
		||||
    Priority:        1
 | 
			
		||||
    SortPriority:    0
 | 
			
		||||
    CaseSensitive:   false
 | 
			
		||||
IncludeIsMainRegex: '(Test)?$'
 | 
			
		||||
IncludeIsMainSourceRegex: ''
 | 
			
		||||
IndentAccessModifiers: false
 | 
			
		||||
IndentCaseLabels: false
 | 
			
		||||
IndentCaseBlocks: false
 | 
			
		||||
IndentGotoLabels: true
 | 
			
		||||
IndentPPDirectives: None
 | 
			
		||||
IndentExternBlock: AfterExternBlock
 | 
			
		||||
IndentRequires:  false
 | 
			
		||||
IndentWidth:     4
 | 
			
		||||
IndentWrappedFunctionNames: false
 | 
			
		||||
InsertTrailingCommas: None
 | 
			
		||||
JavaScriptQuotes: Leave
 | 
			
		||||
JavaScriptWrapImports: true
 | 
			
		||||
KeepEmptyLinesAtTheStartOfBlocks: true
 | 
			
		||||
LambdaBodyIndentation: Signature
 | 
			
		||||
MacroBlockBegin: ''
 | 
			
		||||
MacroBlockEnd:   ''
 | 
			
		||||
MaxEmptyLinesToKeep: 1
 | 
			
		||||
NamespaceIndentation: None
 | 
			
		||||
ObjCBinPackProtocolList: Auto
 | 
			
		||||
ObjCBlockIndentWidth: 2
 | 
			
		||||
ObjCBreakBeforeNestedBlockParam: true
 | 
			
		||||
ObjCSpaceAfterProperty: false
 | 
			
		||||
ObjCSpaceBeforeProtocolList: true
 | 
			
		||||
PenaltyBreakAssignment: 2
 | 
			
		||||
PenaltyBreakBeforeFirstCallParameter: 19
 | 
			
		||||
PenaltyBreakComment: 300
 | 
			
		||||
PenaltyBreakFirstLessLess: 120
 | 
			
		||||
PenaltyBreakOpenParenthesis: 0
 | 
			
		||||
PenaltyBreakString: 1000
 | 
			
		||||
PenaltyBreakTemplateDeclaration: 10
 | 
			
		||||
PenaltyExcessCharacter: 1000000
 | 
			
		||||
PenaltyReturnTypeOnItsOwnLine: 1000
 | 
			
		||||
PenaltyIndentedWhitespace: 0
 | 
			
		||||
PointerAlignment: Right
 | 
			
		||||
PPIndentWidth:   -1
 | 
			
		||||
ReferenceAlignment: Pointer
 | 
			
		||||
ReflowComments:  true
 | 
			
		||||
RemoveBracesLLVM: false
 | 
			
		||||
SeparateDefinitionBlocks: Leave
 | 
			
		||||
ShortNamespaceLines: 1
 | 
			
		||||
SortIncludes:    CaseSensitive
 | 
			
		||||
SortJavaStaticImport: Before
 | 
			
		||||
SortUsingDeclarations: true
 | 
			
		||||
SpaceAfterCStyleCast: false
 | 
			
		||||
SpaceAfterLogicalNot: false
 | 
			
		||||
SpaceAfterTemplateKeyword: true
 | 
			
		||||
SpaceBeforeAssignmentOperators: true
 | 
			
		||||
SpaceBeforeCaseColon: false
 | 
			
		||||
SpaceBeforeCpp11BracedList: false
 | 
			
		||||
SpaceBeforeCtorInitializerColon: true
 | 
			
		||||
SpaceBeforeInheritanceColon: true
 | 
			
		||||
SpaceBeforeParens: ControlStatements
 | 
			
		||||
SpaceBeforeParensOptions:
 | 
			
		||||
  AfterControlStatements: true
 | 
			
		||||
  AfterForeachMacros: true
 | 
			
		||||
  AfterFunctionDefinitionName: false
 | 
			
		||||
  AfterFunctionDeclarationName: false
 | 
			
		||||
  AfterIfMacros:   true
 | 
			
		||||
  AfterOverloadedOperator: false
 | 
			
		||||
  BeforeNonEmptyParentheses: false
 | 
			
		||||
SpaceAroundPointerQualifiers: Default
 | 
			
		||||
SpaceBeforeRangeBasedForLoopColon: true
 | 
			
		||||
SpaceInEmptyBlock: false
 | 
			
		||||
SpaceInEmptyParentheses: false
 | 
			
		||||
SpacesBeforeTrailingComments: 1
 | 
			
		||||
SpacesInAngles:  Never
 | 
			
		||||
SpacesInConditionalStatement: false
 | 
			
		||||
SpacesInContainerLiterals: true
 | 
			
		||||
SpacesInCStyleCastParentheses: false
 | 
			
		||||
SpacesInLineCommentPrefix:
 | 
			
		||||
  Minimum:         1
 | 
			
		||||
  Maximum:         -1
 | 
			
		||||
SpacesInParentheses: false
 | 
			
		||||
SpacesInSquareBrackets: false
 | 
			
		||||
SpaceBeforeSquareBrackets: false
 | 
			
		||||
BitFieldColonSpacing: Both
 | 
			
		||||
Standard:        Latest
 | 
			
		||||
StatementAttributeLikeMacros:
 | 
			
		||||
  - Q_EMIT
 | 
			
		||||
StatementMacros:
 | 
			
		||||
  - Q_UNUSED
 | 
			
		||||
  - QT_REQUIRE_VERSION
 | 
			
		||||
TabWidth:        4
 | 
			
		||||
UseCRLF:         false
 | 
			
		||||
UseTab:          Never
 | 
			
		||||
WhitespaceSensitiveMacros:
 | 
			
		||||
  - STRINGIZE
 | 
			
		||||
  - PP_STRINGIZE
 | 
			
		||||
  - BOOST_PP_STRINGIZE
 | 
			
		||||
  - NS_SWIFT_NAME
 | 
			
		||||
  - CF_SWIFT_NAME
 | 
			
		||||
...
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
.trash/
 | 
			
		||||
.dev/
 | 
			
		||||
 | 
			
		||||
spec.md
 | 
			
		||||
default.nix
 | 
			
		||||
 | 
			
		||||
lbr
 | 
			
		||||
 | 
			
		||||
std/
 | 
			
		||||
							
								
								
									
										11
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
 | 
			
		||||
Version 2, December 2004
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
 | 
			
		||||
 | 
			
		||||
Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed.
 | 
			
		||||
 | 
			
		||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
 | 
			
		||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
			
		||||
 | 
			
		||||
  0. You just DO WHAT THE FUCK YOU WANT TO.
 | 
			
		||||
							
								
								
									
										7
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
CC=clang
 | 
			
		||||
 | 
			
		||||
all:
 | 
			
		||||
	$(CC) -o lbr -O2 -Wall -Wextra -Wpedantic src/*.c
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
	./lbr tests/test.lb
 | 
			
		||||
							
								
								
									
										9
									
								
								src/config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/config.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#define STACK_SIZE 65535
 | 
			
		||||
#define PROGRAM_MAXSIZE 65535
 | 
			
		||||
#define MAX_LABELS 256
 | 
			
		||||
#define MAX_MODULES 256
 | 
			
		||||
#define MAX_BF_LOOPS 256
 | 
			
		||||
 | 
			
		||||
#define DEBUG_MODE 0
 | 
			
		||||
							
								
								
									
										572
									
								
								src/execute.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										572
									
								
								src/execute.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,572 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "execute.h"
 | 
			
		||||
#include "stack.h"
 | 
			
		||||
 | 
			
		||||
#define NAME stack->program[stack->program_counter].name
 | 
			
		||||
#define DATA stack->program[stack->program_counter].data
 | 
			
		||||
#define ARG stack->program[stack->program_counter].arg
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    MPUSH = '>',
 | 
			
		||||
    MDROP = '$',
 | 
			
		||||
    MDUP = ':',
 | 
			
		||||
    MSWAP = '\\',
 | 
			
		||||
    MINC = '+',
 | 
			
		||||
    MDEC = '-',
 | 
			
		||||
 | 
			
		||||
    PPIPE = '|',
 | 
			
		||||
    PREFLECT = '^'
 | 
			
		||||
} OP;
 | 
			
		||||
 | 
			
		||||
static void prefix_operator(Stack *stack, char op)
 | 
			
		||||
{
 | 
			
		||||
    if (NAME[0] != '@' && (NAME[1] == '\0' || NAME[1] == '\n'))
 | 
			
		||||
    {
 | 
			
		||||
        printf("%c\n", op);
 | 
			
		||||
        kms(stack, "Invalid usage of prefix operators");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (op)
 | 
			
		||||
    {
 | 
			
		||||
    case PPIPE:
 | 
			
		||||
        NAME++;
 | 
			
		||||
 | 
			
		||||
        DATA = stack_pop(stack);
 | 
			
		||||
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case PREFLECT:
 | 
			
		||||
        NAME++;
 | 
			
		||||
 | 
			
		||||
        if (NAME[0] != '#' && NAME[0] != '$')
 | 
			
		||||
            printf("%s %i", NAME, DATA);
 | 
			
		||||
 | 
			
		||||
        else if (!strcmp(ARG, "\n"))
 | 
			
		||||
            printf("%s", NAME);
 | 
			
		||||
 | 
			
		||||
        else
 | 
			
		||||
            printf("%s %s", NAME, ARG);
 | 
			
		||||
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void expression(Stack *stack, char *code)
 | 
			
		||||
{
 | 
			
		||||
    uint16_t ax, ax2;
 | 
			
		||||
 | 
			
		||||
    for (uint16_t i = 0; code[i] != '\0'; i++)
 | 
			
		||||
    {
 | 
			
		||||
        switch (code[i])
 | 
			
		||||
        {
 | 
			
		||||
        case MPUSH:
 | 
			
		||||
            stack_push(stack, 0);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case MDROP:
 | 
			
		||||
            stack_pop(stack);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case MDUP:
 | 
			
		||||
            stack_push(stack, stack_peek(stack));
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case MSWAP:
 | 
			
		||||
            ax = stack_pop(stack);
 | 
			
		||||
            ax2 = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, ax);
 | 
			
		||||
            stack_push(stack, ax2);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case MINC:
 | 
			
		||||
            ax = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, ax + 1);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case MDEC:
 | 
			
		||||
            ax = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, ax - 1);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            printf("INVALID EXPRESSION: UNKNOWN OPERATOR '%c'\n", code[i]);
 | 
			
		||||
            kms(stack, "INVALID EXPRESSION");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void find_labels(Stack *stack)
 | 
			
		||||
{
 | 
			
		||||
    for (; stack->program_counter < stack->program_size; stack->program_counter++)
 | 
			
		||||
    {
 | 
			
		||||
        if (NAME[0] == '@')
 | 
			
		||||
        {
 | 
			
		||||
            if (DATA > MAX_LABELS)
 | 
			
		||||
            {
 | 
			
		||||
                printf("INVALID LABEL: %i\n", DATA);
 | 
			
		||||
                kms(stack, "INVALID LABEL");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (stack->labels[DATA] != -1)
 | 
			
		||||
            {
 | 
			
		||||
                printf("LABEL ALREADY DEFINED: %i\n", DATA);
 | 
			
		||||
                kms(stack, "LABEL ALREADY DEFINED");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (DATA == 0)
 | 
			
		||||
            {
 | 
			
		||||
                stack->labels[0] = stack->program_counter;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            stack->labels[DATA] = stack->program_counter;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (stack->labels[0] != -1)
 | 
			
		||||
        stack->program_counter = stack->labels[0];
 | 
			
		||||
    else
 | 
			
		||||
        stack->program_counter = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void execute(Stack *stack, Stack *originstack, char *modname)
 | 
			
		||||
{
 | 
			
		||||
    find_labels(stack);
 | 
			
		||||
 | 
			
		||||
    for (; stack->program_counter < stack->program_size; stack->program_counter++)
 | 
			
		||||
    {
 | 
			
		||||
        prefix_operator(stack, NAME[0]);
 | 
			
		||||
 | 
			
		||||
        if (NAME[0] == '@')
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        // Stack operations
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "push")) // arg <uint16>
 | 
			
		||||
        {
 | 
			
		||||
            stack_push(stack, DATA);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "pop"))
 | 
			
		||||
        {
 | 
			
		||||
            stack_pop(stack);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "dup"))
 | 
			
		||||
        {
 | 
			
		||||
            stack_push(stack, stack_peek(stack));
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "swap"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t a = stack_pop(stack);
 | 
			
		||||
            uint16_t b = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, a);
 | 
			
		||||
            stack_push(stack, b);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "pick"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t arg = stack_pop(stack);
 | 
			
		||||
 | 
			
		||||
            if (arg >= stack->pointer)
 | 
			
		||||
                kms(stack, "ATTEMPTED TO PICK BELOW STACK");
 | 
			
		||||
 | 
			
		||||
            stack_push(stack, stack->memory[stack->pointer - arg - 1]);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Math
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "add"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t a = stack_pop(stack);
 | 
			
		||||
            uint16_t b = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, b + a);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "sub"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t a = stack_pop(stack);
 | 
			
		||||
            uint16_t b = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, b - a);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "mul"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t a = stack_pop(stack);
 | 
			
		||||
            uint16_t b = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, b * a);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "div"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t a = stack_pop(stack);
 | 
			
		||||
            uint16_t b = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, b / a);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "mod"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t a = stack_pop(stack);
 | 
			
		||||
            uint16_t b = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, b % a);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Logic
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "and"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t a = stack_pop(stack);
 | 
			
		||||
            uint16_t b = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, a && b);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "or"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t a = stack_pop(stack);
 | 
			
		||||
            uint16_t b = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, a || b);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "xor"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t a = stack_pop(stack);
 | 
			
		||||
            uint16_t b = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, !a != !b);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "nand"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t a = stack_pop(stack);
 | 
			
		||||
            uint16_t b = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, !(a && b));
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "not"))
 | 
			
		||||
        {
 | 
			
		||||
            stack_push(stack, !stack_pop(stack));
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Bitwise
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "band"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t a = stack_pop(stack);
 | 
			
		||||
            uint16_t b = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, a & b);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "bor"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t a = stack_pop(stack);
 | 
			
		||||
            uint16_t b = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, a | b);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "bxor"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t a = stack_pop(stack);
 | 
			
		||||
            uint16_t b = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, a ^ b);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "bnand"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t a = stack_pop(stack);
 | 
			
		||||
            uint16_t b = stack_pop(stack);
 | 
			
		||||
            stack_push(stack, ~(a & b));
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "bnot"))
 | 
			
		||||
        {
 | 
			
		||||
            stack_push(stack, ~stack_pop(stack));
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Flow control
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "jmp")) // arg <uint16>
 | 
			
		||||
        {
 | 
			
		||||
            if (stack->labels[DATA] == -1)
 | 
			
		||||
            {
 | 
			
		||||
                printf("UNKNOWN LABEL: %i\n", DATA);
 | 
			
		||||
                kms(stack, "UNKNOWN LABEL");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            stack->program_counter = stack->labels[DATA];
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "jnz")) // arg <uint16>
 | 
			
		||||
        {
 | 
			
		||||
            if (stack->labels[DATA] == -1)
 | 
			
		||||
            {
 | 
			
		||||
                printf("UNKNOWN LABEL: %i\n", DATA);
 | 
			
		||||
                kms(stack, "UNKNOWN LABEL");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (stack_pop(stack) != 0)
 | 
			
		||||
                stack->program_counter = stack->labels[DATA];
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "jz")) // arg <uint16>
 | 
			
		||||
        {
 | 
			
		||||
            if (stack->labels[DATA] == -1)
 | 
			
		||||
            {
 | 
			
		||||
                printf("UNKNOWN LABEL: %i\n", DATA);
 | 
			
		||||
                kms(stack, "UNKNOWN LABEL");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (stack_pop(stack) == 0)
 | 
			
		||||
                stack->program_counter = stack->labels[DATA];
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "kjnz")) // arg <uint16>
 | 
			
		||||
        {
 | 
			
		||||
            if (stack->labels[DATA] == -1)
 | 
			
		||||
            {
 | 
			
		||||
                printf("UNKNOWN LABEL: %i\n", DATA);
 | 
			
		||||
                kms(stack, "UNKNOWN LABEL");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (stack_peek(stack) != 0)
 | 
			
		||||
                stack->program_counter = stack->labels[DATA];
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "kjz")) // arg <uint16>
 | 
			
		||||
        {
 | 
			
		||||
            if (stack->labels[DATA] == -1)
 | 
			
		||||
            {
 | 
			
		||||
                printf("UNKNOWN LABEL: %i\n", DATA);
 | 
			
		||||
                kms(stack, "UNKNOWN LABEL");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (stack_peek(stack) == 0)
 | 
			
		||||
                stack->program_counter = stack->labels[DATA];
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // I/O
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "putc"))
 | 
			
		||||
        {
 | 
			
		||||
            putchar(stack_pop(stack));
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "getc"))
 | 
			
		||||
        {
 | 
			
		||||
            stack_push(stack, getchar());
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "scan"))
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t num;
 | 
			
		||||
            scanf("%hu", &num);
 | 
			
		||||
            stack_push(stack, num);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "meow"))
 | 
			
		||||
        {
 | 
			
		||||
            printf("%i\n", stack_pop(stack));
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "$println")) // arg <string>
 | 
			
		||||
        {
 | 
			
		||||
            printf("%s\n", ARG);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "#println")) // arg <string>
 | 
			
		||||
        {
 | 
			
		||||
            printf("%s\n", ARG);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "$print")) // arg <string>
 | 
			
		||||
        {
 | 
			
		||||
            printf("%s", ARG);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "#print")) // arg <const>
 | 
			
		||||
        {
 | 
			
		||||
            printf("%s", ARG);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Modules
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "args")) // arg <uint16>
 | 
			
		||||
        {
 | 
			
		||||
            if (!originstack)
 | 
			
		||||
                kms(stack, "ATTEMPTED TO USE ARGS IN THE MAIN MODULE");
 | 
			
		||||
 | 
			
		||||
            if (DATA > STACK_SIZE)
 | 
			
		||||
                kms(stack, "ATTEMPTED TO POP MORE THAN STACK_SIZE ARGUMENTS");
 | 
			
		||||
 | 
			
		||||
            if (DATA == 0)
 | 
			
		||||
                DATA = stack_pop(originstack);
 | 
			
		||||
 | 
			
		||||
            uint16_t ddata = DATA;
 | 
			
		||||
 | 
			
		||||
            while (ddata != 0)
 | 
			
		||||
            {
 | 
			
		||||
                stack_push(stack, stack_pop(originstack));
 | 
			
		||||
                ddata--;
 | 
			
		||||
            }
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "#exec")) // arg <const>
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            if (!strcmp(ARG, modname))
 | 
			
		||||
            {
 | 
			
		||||
                printf("MODULE %s: CAN'T EXECUTE ITSELF\n", ARG);
 | 
			
		||||
                kms(stack, "CAN'T EXECUTE ITSELF");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            FILE *file = fopen(ARG, "r");
 | 
			
		||||
            if (!file)
 | 
			
		||||
            {
 | 
			
		||||
                printf("ERROR OPENING MODULE: %s\n", ARG);
 | 
			
		||||
                kms(stack, "ERROR OPENING MODULE");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            DATA = DATA ? DATA : STACK_SIZE;
 | 
			
		||||
 | 
			
		||||
            Stack *tempstack = program_init(DATA);
 | 
			
		||||
 | 
			
		||||
            parse_and_process(tempstack, file);
 | 
			
		||||
 | 
			
		||||
            fclose(file);
 | 
			
		||||
 | 
			
		||||
            execute(tempstack, stack, ARG);
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < tempstack->pointer; i++)
 | 
			
		||||
                stack_push(stack, tempstack->memory[i]);
 | 
			
		||||
 | 
			
		||||
            free(tempstack);
 | 
			
		||||
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Self-modifying
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "#insert")) // arg <const>
 | 
			
		||||
        {
 | 
			
		||||
            if (ARG[0] == '#' || ARG[0] == '$')
 | 
			
		||||
                kms(stack, "ATTEMPTED TO INSERT A HASH/STRING-INSTRUCTION");
 | 
			
		||||
 | 
			
		||||
            if (ARG[0] == '\n')
 | 
			
		||||
                kms(stack, "ATTEMPTED TO INSERT AN EMPTY CONSTANT");
 | 
			
		||||
 | 
			
		||||
            if (ARG[0] == '@' && ARG[1] == ' ')
 | 
			
		||||
                kms(stack, "ATTEMPTED TO INSERT A LABEL");
 | 
			
		||||
 | 
			
		||||
            stack->program[stack->program_size++] = (Instruction){ARG, "\n", DATA};
 | 
			
		||||
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Special
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "dump"))
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = 0; i < stack->pointer; i++)
 | 
			
		||||
                printf("%d: %d\n", i, stack->memory[i]);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "size"))
 | 
			
		||||
        {
 | 
			
		||||
            int i = 0;
 | 
			
		||||
            while (i < stack->pointer)
 | 
			
		||||
                i++;
 | 
			
		||||
 | 
			
		||||
            stack_push(stack, i);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "maxsize"))
 | 
			
		||||
        {
 | 
			
		||||
            stack_push(stack, stack->stacksize);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "#expr")) // arg <const>
 | 
			
		||||
        {
 | 
			
		||||
            expression(stack, ARG);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "nop"))
 | 
			
		||||
        {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "quit"))
 | 
			
		||||
        {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "exit"))
 | 
			
		||||
        {
 | 
			
		||||
            exit(stack_pop(stack));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Platform-specific
 | 
			
		||||
 | 
			
		||||
#ifdef __unix__
 | 
			
		||||
 | 
			
		||||
        if (!strcmp(NAME, "_unix_random"))
 | 
			
		||||
        {
 | 
			
		||||
            srand(getc(fopen("/dev/urandom", "r")));
 | 
			
		||||
            stack_push(stack, rand() % stack_pop(stack));
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        // LBR-SPECIFIC
 | 
			
		||||
        printf("UNKNOWN INSTRUCTION: %s\n", NAME);
 | 
			
		||||
        kms(stack, "UNKNOWN INSTRUCTION");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef NAME
 | 
			
		||||
#undef ARG
 | 
			
		||||
#undef DATA
 | 
			
		||||
							
								
								
									
										3
									
								
								src/execute.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/execute.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
#include "stack.h"
 | 
			
		||||
 | 
			
		||||
void execute(Stack *stack, Stack *originstack, char *modname);
 | 
			
		||||
							
								
								
									
										34
									
								
								src/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/main.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "execute.h"
 | 
			
		||||
#include "stack.h"
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    if (argc < 2)
 | 
			
		||||
    {
 | 
			
		||||
        fprintf(stderr, "Usage: %s [FILE]\n", argv[0]);
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Stack *stack = program_init(STACK_SIZE);
 | 
			
		||||
 | 
			
		||||
    FILE *file = fopen(argv[1], "r");
 | 
			
		||||
    if (!file)
 | 
			
		||||
    {
 | 
			
		||||
        perror("fopen()");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    parse_and_process(stack, file);
 | 
			
		||||
 | 
			
		||||
    fclose(file);
 | 
			
		||||
 | 
			
		||||
    execute(stack, (void *)0, argv[1]);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										100
									
								
								src/stack.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								src/stack.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,100 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "stack.h"
 | 
			
		||||
 | 
			
		||||
Stack *program_init(uint16_t stacksize)
 | 
			
		||||
{
 | 
			
		||||
    Stack *stack = malloc(sizeof(&stack) + sizeof(Instruction) * PROGRAM_MAXSIZE + sizeof(int16_t) * MAX_LABELS +
 | 
			
		||||
                          sizeof(uint16_t) * stacksize);
 | 
			
		||||
 | 
			
		||||
    stack->stacksize = stacksize;
 | 
			
		||||
 | 
			
		||||
    for (unsigned int i = 0; i < MAX_LABELS; i++)
 | 
			
		||||
        stack->labels[i] = -1; // костыль ебанный
 | 
			
		||||
 | 
			
		||||
    return stack;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void stack_push(Stack *stack, uint16_t data)
 | 
			
		||||
{
 | 
			
		||||
    if (stack->pointer > STACK_SIZE)
 | 
			
		||||
        kms(stack, "STACK OVERFLOW");
 | 
			
		||||
    stack->memory[stack->pointer++] = data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t stack_pop(Stack *stack)
 | 
			
		||||
{
 | 
			
		||||
    if (stack->pointer <= 0)
 | 
			
		||||
        kms(stack, "STACK UNDERFLOW");
 | 
			
		||||
    return stack->memory[--stack->pointer];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t stack_peek(Stack *stack)
 | 
			
		||||
{
 | 
			
		||||
    return stack->memory[stack->pointer - 1];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void kms(Stack *stack, const char *err)
 | 
			
		||||
{
 | 
			
		||||
    if (DEBUG_MODE)
 | 
			
		||||
        for (int i = 0; i < stack->pointer; i++)
 | 
			
		||||
            printf("%d: %d\n", i, stack->memory[i]);
 | 
			
		||||
 | 
			
		||||
    fprintf(stderr, "%s", err);
 | 
			
		||||
    free(stack);
 | 
			
		||||
    exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void parse_and_process(Stack *stack, FILE *file)
 | 
			
		||||
{
 | 
			
		||||
    char *line = NULL;
 | 
			
		||||
    size_t len = 0;
 | 
			
		||||
 | 
			
		||||
    while (getline(&line, &len, file) != -1)
 | 
			
		||||
    {
 | 
			
		||||
        if (line[0] == ';')
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        line[strcspn(line, "\n")] = 0;
 | 
			
		||||
        unsigned long com = strcspn(line, ";");
 | 
			
		||||
        if (com)
 | 
			
		||||
            line[com] = '\0'; // шоб пропустил комментарий
 | 
			
		||||
 | 
			
		||||
        Instruction inst;
 | 
			
		||||
        memset(&inst, 0, sizeof(inst)); // обнуляем структуру на всякий если
 | 
			
		||||
        // вернутся старые значения
 | 
			
		||||
 | 
			
		||||
        inst.name = strtok(line, " ");
 | 
			
		||||
        if (!inst.name)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        if (inst.name[0] == 9)
 | 
			
		||||
        {
 | 
			
		||||
            printf("Tabs are not allowed!\n");
 | 
			
		||||
            exit(1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        char *data = strtok(NULL, "");
 | 
			
		||||
 | 
			
		||||
        if (!data)
 | 
			
		||||
            data = 0;
 | 
			
		||||
        else if (inst.name[0] == '#' || inst.name[1] == '#')
 | 
			
		||||
            inst.arg = strtok(data, " ");
 | 
			
		||||
        else if (inst.name[0] == '$' || inst.name[1] == '$')
 | 
			
		||||
            inst.arg = data;
 | 
			
		||||
        else
 | 
			
		||||
            inst.data = strtol(data, NULL, 10);
 | 
			
		||||
 | 
			
		||||
        char *duppedname = strdup(inst.name);
 | 
			
		||||
 | 
			
		||||
        if (!inst.arg)
 | 
			
		||||
            inst.arg = "\n";
 | 
			
		||||
        char *duppedarg = strdup(inst.arg);
 | 
			
		||||
 | 
			
		||||
        stack->program[stack->program_size++] = (Instruction){duppedname, duppedarg, inst.data};
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								src/stack.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/stack.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    char *name;
 | 
			
		||||
    char *arg;
 | 
			
		||||
    uint16_t data;
 | 
			
		||||
} Instruction;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    Instruction program[PROGRAM_MAXSIZE];
 | 
			
		||||
    uint16_t program_size, program_counter, stacksize;
 | 
			
		||||
    int pointer;
 | 
			
		||||
    int16_t labels[MAX_LABELS];
 | 
			
		||||
    uint16_t memory[];
 | 
			
		||||
} Stack;
 | 
			
		||||
 | 
			
		||||
Stack *program_init(uint16_t stacksize);
 | 
			
		||||
 | 
			
		||||
void stack_push(Stack *stack, uint16_t data);
 | 
			
		||||
 | 
			
		||||
uint16_t stack_pop(Stack *stack);
 | 
			
		||||
 | 
			
		||||
uint16_t stack_peek(Stack *stack);
 | 
			
		||||
 | 
			
		||||
void kms(Stack *stack, const char *err);
 | 
			
		||||
 | 
			
		||||
void parse_and_process(Stack *stack, FILE *file);
 | 
			
		||||
 | 
			
		||||
void repl(Stack *stack);
 | 
			
		||||
							
								
								
									
										25
									
								
								tests/calc.lb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								tests/calc.lb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,25 @@
 | 
			
		||||
@ 0
 | 
			
		||||
    scan
 | 
			
		||||
    scan
 | 
			
		||||
    scan
 | 
			
		||||
    |jmp 0
 | 
			
		||||
 | 
			
		||||
@ 1
 | 
			
		||||
    add
 | 
			
		||||
    meow
 | 
			
		||||
    quit
 | 
			
		||||
 | 
			
		||||
@ 2
 | 
			
		||||
    sub
 | 
			
		||||
    meow
 | 
			
		||||
    quit 
 | 
			
		||||
 | 
			
		||||
@ 3
 | 
			
		||||
    mul
 | 
			
		||||
    meow
 | 
			
		||||
    quit
 | 
			
		||||
 | 
			
		||||
@ 4
 | 
			
		||||
    div
 | 
			
		||||
    meow
 | 
			
		||||
    quit
 | 
			
		||||
							
								
								
									
										16
									
								
								tests/helloworld.lb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								tests/helloworld.lb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
PUSH 76  ; L
 | 
			
		||||
PUTC
 | 
			
		||||
PUSH 97  ; a
 | 
			
		||||
PUTC
 | 
			
		||||
PUSH 98  ; b
 | 
			
		||||
PUTC
 | 
			
		||||
PUSH 97  ; a
 | 
			
		||||
PUTC
 | 
			
		||||
PUSH 115 ; s
 | 
			
		||||
PUTC
 | 
			
		||||
PUSH 104 ; h
 | 
			
		||||
PUTC
 | 
			
		||||
PUSH 107 ; k
 | 
			
		||||
PUTC
 | 
			
		||||
PUSH 105 ; i
 | 
			
		||||
PUTC
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user