Read array elements
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
@extern putchar fun: character sint32 -> sint32
|
||||
|
||||
main fun -> sint32
|
||||
text data<sint32> <- "Hello string!\n"
|
||||
|
||||
rep i sint32 <- 0, i < 14:
|
||||
text data<sint32> <- "Hello, world!\n"
|
||||
|
||||
rep i sint32 <- 0, text[i] != 0:
|
||||
putchar(text[i])
|
||||
i <- i + 1
|
||||
;
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
@extern putchar fun: character sint32 -> sint32
|
||||
|
||||
/*
|
||||
User type
|
||||
name data<u8, 32>
|
||||
age u32
|
||||
successRatio r32
|
||||
isActive bool
|
||||
;
|
||||
*/
|
||||
|
||||
/*
|
||||
i u32 <- 0, rep text[i] != 0:
|
||||
putchar(text[i])
|
||||
i++
|
||||
;
|
||||
*/
|
||||
|
||||
// text data<u8> <- "Hello world!"
|
||||
|
||||
main fun -> sint32
|
||||
text data<sint32> <- "Hello string!\n"
|
||||
|
||||
|
||||
@@ -132,12 +132,15 @@ void ModuleBuilder::buildVarDeclaration(shared_ptr<StatementVariable> statement)
|
||||
|
||||
llvm::ArrayType *type = (llvm::ArrayType *)typeForValueType(statement->getValueType(), values.size());
|
||||
llvm::AllocaInst *alloca = builder->CreateAlloca(type, nullptr, statement->getName());
|
||||
if (!setAlloca(statement->getName(), alloca))
|
||||
return;
|
||||
for (int i=0; i < type->getNumElements(); i++) {
|
||||
llvm::Value *index[] = {
|
||||
builder->getInt32(0),
|
||||
builder->getInt32(i)
|
||||
};
|
||||
llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}_{}", statement->getName(), i));
|
||||
|
||||
builder->CreateStore(values[i], elementPtr);
|
||||
}
|
||||
} else {
|
||||
@@ -150,10 +153,6 @@ void ModuleBuilder::buildVarDeclaration(shared_ptr<StatementVariable> statement)
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleBuilder::buildArrayDeclaration(shared_ptr<StatementVariable> statement) {
|
||||
|
||||
}
|
||||
|
||||
void ModuleBuilder::buildAssignment(shared_ptr<StatementAssignment> statement) {
|
||||
llvm::AllocaInst *alloca = getAlloca(statement->getName());
|
||||
if (alloca == nullptr)
|
||||
@@ -254,7 +253,6 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr<Expression> expression
|
||||
switch (expression->getKind()) {
|
||||
case ExpressionKind::LITERAL:
|
||||
return valueForLiteral(dynamic_pointer_cast<ExpressionLiteral>(expression));
|
||||
|
||||
case ExpressionKind::GROUPING:
|
||||
return valueForExpression(dynamic_pointer_cast<ExpressionGrouping>(expression)->getExpression());
|
||||
case ExpressionKind::BINARY:
|
||||
@@ -313,6 +311,9 @@ llvm::Value *ModuleBuilder::valueForBinary(shared_ptr<ExpressionBinary> expressi
|
||||
llvm::Value *leftValue = valueForExpression(expression->getLeft());
|
||||
llvm::Value *rightValue = valueForExpression(expression->getRight());
|
||||
|
||||
if (leftValue == nullptr || rightValue == nullptr)
|
||||
return nullptr;
|
||||
|
||||
llvm::Type *type = leftValue->getType();
|
||||
|
||||
if (type == typeBool) {
|
||||
@@ -450,7 +451,19 @@ llvm::Value *ModuleBuilder::valueForVar(shared_ptr<ExpressionVariable> expressio
|
||||
if (alloca == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return builder->CreateLoad(alloca->getAllocatedType(), alloca, expression->getName());
|
||||
if (expression->getIndexExpression()) {
|
||||
llvm::Value *indexValue = valueForExpression(expression->getIndexExpression());
|
||||
llvm::Value *index[] = {
|
||||
builder->getInt32(0),
|
||||
indexValue
|
||||
};
|
||||
llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType();
|
||||
llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", expression->getName()));
|
||||
|
||||
return builder->CreateLoad(type->getArrayElementType(), elementPtr);
|
||||
} else {
|
||||
return builder->CreateLoad(alloca->getAllocatedType(), alloca, expression->getName());
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Value *ModuleBuilder::valueForCall(shared_ptr<ExpressionCall> expression) {
|
||||
|
||||
@@ -62,7 +62,6 @@ private:
|
||||
void buildStatement(shared_ptr<Statement> statement);
|
||||
void buildFunctionDeclaration(shared_ptr<StatementFunction> statement);
|
||||
void buildVarDeclaration(shared_ptr<StatementVariable> statement);
|
||||
void buildArrayDeclaration(shared_ptr<StatementVariable> statement);
|
||||
void buildAssignment(shared_ptr<StatementAssignment> statement);
|
||||
void buildBlock(shared_ptr<StatementBlock> statement);
|
||||
void buildReturn(shared_ptr<StatementReturn> statement);
|
||||
|
||||
@@ -376,7 +376,11 @@ string Logger::toString(shared_ptr<ExpressionIfElse> expression) {
|
||||
}
|
||||
|
||||
string Logger::toString(shared_ptr<ExpressionVariable> expression) {
|
||||
return format("VAR({})", expression->getName());
|
||||
string text = format("VAR({}", expression->getName());
|
||||
if (expression->getIndexExpression() != nullptr)
|
||||
text += format("|{}", toString(expression->getIndexExpression()));
|
||||
text += ")";
|
||||
return text;
|
||||
}
|
||||
|
||||
string Logger::toString(shared_ptr<ExpressionGrouping> expression) {
|
||||
|
||||
@@ -26,6 +26,13 @@ shared_ptr<ExpressionArrayLiteral> ExpressionArrayLiteral::expressionArrayLitera
|
||||
shared_ptr<Token> token = make_shared<Token>(TokenKind::INTEGER_CHAR, lexme, tokenString->getLine(), tokenString->getColumn() + i);
|
||||
shared_ptr<ExpressionLiteral> expression = ExpressionLiteral::expressionLiteralForToken(token);
|
||||
expressions.push_back(expression);
|
||||
|
||||
// add terminal 0 if missing
|
||||
if (i == stringValue.length() - 2 && lexme.compare("\\0") != 0) {
|
||||
shared_ptr<Token> token = make_shared<Token>(TokenKind::INTEGER_CHAR, "\\0", tokenString->getLine(), tokenString->getColumn() + i + lexme.length());
|
||||
shared_ptr<ExpressionLiteral> expression = ExpressionLiteral::expressionLiteralForToken(token);
|
||||
expressions.push_back(expression);
|
||||
}
|
||||
}
|
||||
|
||||
expression->expressions = expressions;
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
#include "ExpressionVariable.h"
|
||||
|
||||
ExpressionVariable::ExpressionVariable(string name):
|
||||
Expression(ExpressionKind::VAR, nullptr), name(name) { }
|
||||
ExpressionVariable::ExpressionVariable(string name, shared_ptr<Expression> indexExpression):
|
||||
Expression(ExpressionKind::VAR, nullptr), name(name), indexExpression(indexExpression) { }
|
||||
|
||||
string ExpressionVariable::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> ExpressionVariable::getIndexExpression() {
|
||||
return indexExpression;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
class ExpressionVariable: public Expression {
|
||||
private:
|
||||
string name;
|
||||
shared_ptr<Expression> indexExpression;
|
||||
|
||||
public:
|
||||
ExpressionVariable(string name);
|
||||
ExpressionVariable(string name, shared_ptr<Expression> indexExpression);
|
||||
string getName();
|
||||
shared_ptr<Expression> getIndexExpression();
|
||||
};
|
||||
@@ -292,7 +292,7 @@ shared_ptr<Statement> Parser::matchStatementRepeat() {
|
||||
// got initial, expect comma
|
||||
if (initStatement != nullptr && !tryMatchingTokenKinds({TokenKind::COMMA}, true, true)) {
|
||||
markError(TokenKind::COMMA, {});
|
||||
return nullptr;
|
||||
goto afterIf;
|
||||
}
|
||||
|
||||
// optional new line
|
||||
@@ -305,7 +305,7 @@ shared_ptr<Statement> Parser::matchStatementRepeat() {
|
||||
// got pre-condition, expect comma
|
||||
if (!tryMatchingTokenKinds({TokenKind::COMMA}, true, true)) {
|
||||
markError(TokenKind::COMMA, {});
|
||||
return nullptr;
|
||||
goto afterIf;
|
||||
}
|
||||
|
||||
// optional new line
|
||||
@@ -317,10 +317,11 @@ shared_ptr<Statement> Parser::matchStatementRepeat() {
|
||||
// expect colon
|
||||
if (!tryMatchingTokenKinds({TokenKind::COLON}, true, true)) {
|
||||
markError(TokenKind::COLON, {});
|
||||
return nullptr;
|
||||
goto afterIf;
|
||||
}
|
||||
}
|
||||
}
|
||||
afterIf:
|
||||
|
||||
isMultiLine = tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true);
|
||||
|
||||
@@ -416,25 +417,26 @@ shared_ptr<Expression> Parser::matchFactor() {
|
||||
|
||||
shared_ptr<Expression> Parser::matchPrimary() {
|
||||
shared_ptr<Expression> expression;
|
||||
int errorsCount = errors.size();
|
||||
|
||||
expression = matchExpressionGrouping();
|
||||
if (expression != nullptr)
|
||||
if (expression != nullptr || errors.size() > errorsCount)
|
||||
return expression;
|
||||
|
||||
expression = matchExpressionArrayLiteral();
|
||||
if (expression != nullptr)
|
||||
if (expression != nullptr || errors.size() > errorsCount)
|
||||
return expression;
|
||||
|
||||
expression = matchExpressionLiteral();
|
||||
if (expression != nullptr)
|
||||
if (expression != nullptr || errors.size() > errorsCount)
|
||||
return expression;
|
||||
|
||||
expression = matchExpressionCall();
|
||||
if (expression != nullptr)
|
||||
if (expression != nullptr || errors.size() > errorsCount)
|
||||
return expression;
|
||||
|
||||
expression = matchExpressionVariable();
|
||||
if (expression != nullptr)
|
||||
if (expression != nullptr || errors.size() > errorsCount)
|
||||
return expression;
|
||||
|
||||
return nullptr;
|
||||
@@ -490,12 +492,23 @@ shared_ptr<Expression> Parser::matchExpressionArrayLiteral() {
|
||||
}
|
||||
|
||||
shared_ptr<Expression> Parser::matchExpressionVariable() {
|
||||
shared_ptr<Token> token = tokens.at(currentIndex);
|
||||
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER}, true, false))
|
||||
return nullptr;
|
||||
shared_ptr<Token> idToken = tokens.at(currentIndex++);
|
||||
shared_ptr<Expression> indexExpression;
|
||||
|
||||
if (tryMatchingTokenKinds({TokenKind::IDENTIFIER}, true, true))
|
||||
return make_shared<ExpressionVariable>(token->getLexme());
|
||||
if (tryMatchingTokenKinds({TokenKind::LEFT_SQUARE_BRACKET}, true, true)) {
|
||||
indexExpression = nextExpression();
|
||||
if (indexExpression == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (!tryMatchingTokenKinds({TokenKind::RIGHT_SQUARE_BRACKET}, true, true)) {
|
||||
markError(TokenKind::RIGHT_SQUARE_BRACKET, {});
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return make_shared<ExpressionVariable>(idToken->getLexme(), indexExpression);
|
||||
}
|
||||
|
||||
shared_ptr<Expression> Parser::matchExpressionCall() {
|
||||
|
||||
@@ -25,6 +25,8 @@ optional<int> Utils::charStringToInt(string charString) {
|
||||
return '\'';
|
||||
case '\"':
|
||||
return '\"';
|
||||
case '0':
|
||||
return '\0';
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user