diff --git a/src/ast.cpp b/src/ast.cpp index 6c78787..26ff5c0 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -9,6 +9,12 @@ namespace AST { return out.str(); } + std::string StringLiteralExpression::formatted() { + std::stringstream out{ "" }; + out << "\"" << this->m_value << "\""; + return out.str(); + } + std::string ValueReferenceExpression::formatted() { return this->m_name; } diff --git a/src/ast.h b/src/ast.h index b1081d9..2a46fde 100644 --- a/src/ast.h +++ b/src/ast.h @@ -41,6 +41,16 @@ namespace AST { virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override; }; + class StringLiteralExpression : public Expression { + private: + std::string m_value; + public: + StringLiteralExpression(token::Metadata meta, std::string value) : Expression{ meta }, m_value{ value } {} + virtual ~StringLiteralExpression() override = default; + virtual std::string formatted() override; + virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override; + }; + class ValueReferenceExpression : public Expression { private: std::string m_name; diff --git a/src/codegen.cpp b/src/codegen.cpp index 7dff78b..4c5917a 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -22,7 +22,19 @@ namespace AST { return codegen::StackValue{ llvm::ConstantInt::get(ty, this->m_value), - std::unique_ptr{stack_type} + std::unique_ptr{stack_type} + }; + } + + codegen::StackValue StringLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope&) { + + auto stack_type = new types::PointerType{ std::make_unique(types::FundamentalTypeKind::Char) }; + + auto str = llvm::StringRef{ this->m_value.c_str() }; + + return codegen::StackValue{ + builder.builder->CreateGlobalString(str), + std::unique_ptr{stack_type}, }; } diff --git a/src/parsing.cpp b/src/parsing.cpp index fe9ab2f..82347ad 100644 --- a/src/parsing.cpp +++ b/src/parsing.cpp @@ -59,6 +59,12 @@ namespace parsing { auto expr = new AST::IntLiteralExpression{ token.metadata, std::stoi(token.content) }; return std::unique_ptr{ expr }; } + else if (token.type == token::Type::LiteralStr) { + stream.m_position = inner.m_position; + + auto expr = new AST::StringLiteralExpression{ token.metadata, token.content }; + return std::unique_ptr{ expr }; + } else if (token.type == token::Type::Ident) { stream.m_position = inner.m_position; diff --git a/src/tokens.cpp b/src/tokens.cpp index ca78699..d6a0642 100644 --- a/src/tokens.cpp +++ b/src/tokens.cpp @@ -23,6 +23,8 @@ namespace token { return "Symbol"; case token::Type::LiteralInt: return "LiteralInt"; + case token::Type::LiteralStr: + return "LiteralStr"; case token::Type::ReturnKeyword: return "Return"; @@ -140,6 +142,16 @@ namespace token { } while (std::isdigit(c)); tokens.push_back(token::Token{ token::Type::LiteralInt, content, meta + content.size() }); } + else if (c == '\"') { + std::string content{}; + c = text[++i]; // Skip initial " + do { + content += c; + c = text[++i]; + } while (c != '\"'); + i++; // Skip second " + tokens.push_back(token::Token{ token::Type::LiteralStr, content, meta + (content.size() + 2) }); + } else if (std::isalpha(c)) { std::string content{}; do { diff --git a/src/tokens.h b/src/tokens.h index 9ba23b9..a52fd6d 100644 --- a/src/tokens.h +++ b/src/tokens.h @@ -11,6 +11,7 @@ namespace token { Ident, Symbol, LiteralInt, + LiteralStr, ReturnKeyword, IfKeyword, diff --git a/test.c b/test.c index 20838a3..1d57237 100644 --- a/test.c +++ b/test.c @@ -7,5 +7,6 @@ int fibonacci(int n) { } int main() { + printf("hello world!"); return fibonacci(10); } \ No newline at end of file