diff --git a/Amogulator.csproj b/Amogulator.csproj
index 2623758..196bb0d 100644
--- a/Amogulator.csproj
+++ b/Amogulator.csproj
@@ -1,14 +1,18 @@
-
- WinExe
- net7.0-windows
- enable
- true
-
+
+ WinExe
+ net7.0-windows
+ enable
+ true
+
-
-
-
+
+
+
+
+
+
+
diff --git a/Suslang/Suslang.cs b/Suslang/Suslang.cs
new file mode 100644
index 0000000..7ccd1f8
--- /dev/null
+++ b/Suslang/Suslang.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Collections.Generic;
+
+namespace Amogulator.Suslang;
+
+public enum TokenType {
+ Eof,
+ Invalid,
+ Id,
+ Int,
+ Hex,
+ Decimal,
+ String,
+ True,
+ False,
+ LParen,
+ RParen,
+ Plus,
+ Minus,
+ Asterisk,
+ Slash,
+ Percent,
+}
+
+public struct Position {
+ public int index;
+ public int line, col;
+}
+
+public struct Token {
+ public TokenType type;
+ public Position position;
+ public int length;
+}
+
+public class Lexer {
+ private int i = 0;
+ private string text;
+ private int line = 1;
+ private int col = 1;
+
+ public Lexer(string text) {
+ this.text = text;
+ }
+
+ public Token next() {
+ if (done()) {
+ return token(TokenType.Eof, position());
+ } else if ("123456789".Contains(current())) {
+ return intToken();
+ } else if ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_".Contains(current())) {
+ return idToken();
+ } else {
+ return staticToken();
+ }
+ }
+
+ private Token intToken() {
+ var start = position();
+ var value = "";
+ value += current();
+ step();
+ while (!done() && "1234567890".Contains(current())) {
+ value += current();
+ step();
+ }
+ return token(TokenType.Int, start);
+ }
+
+ private Token idToken() {
+ var start = position();
+ var value = "";
+ value += current();
+ step();
+ while (!done() && "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_".Contains(current())) {
+ value += current();
+ step();
+ }
+ return token(TokenType.Id, start);
+ }
+
+ private Token staticToken() {
+ var start = position();
+ switch (current()) {
+ case '(':
+ step();
+ return token(TokenType.LParen, start);
+ case ')':
+ step();
+ return token(TokenType.RParen, start);
+ case '+':
+ step();
+ return token(TokenType.Plus, start);
+ case '-':
+ step();
+ return token(TokenType.Minus, start);
+ case '*':
+ step();
+ return token(TokenType.Asterisk, start);
+ case '/':
+ step();
+ return token(TokenType.Slash, start);
+ case '%':
+ step();
+ return token(TokenType.Percent, start);
+ default:
+ step();
+ return token(TokenType.Invalid, start);
+ }
+ }
+
+ private Token token(TokenType type, Position start) => new Token() {
+ type = type,
+ position = start,
+ length = this.i - start.index,
+ };
+
+ private Position position() => new Position() {
+ index = this.i,
+ line = this.line,
+ col = this.col,
+ };
+
+ private char current() => this.text[this.i];
+ private bool done() => this.i >= this.text.Length;
+
+ private void step() {
+ this.i += 1;
+ }
+}
+
+public interface Expr {
+
+}
+
+public class Parser {
+ public Expr parseExpr() {
+ throw new NotImplementedException();
+ }
+}
+
+public interface Operation {
+}
+
+public class Compiler {
+ public List compileExpr(Expr expr) {
+ throw new NotImplementedException();
+ }
+}
+
+public interface Value { }
+
+public class VM {
+ public Value evaluate(List program) {
+ throw new NotImplementedException();
+ }
+}