...
This commit is contained in:
@@ -1,11 +1,17 @@
|
|||||||
namespace main
|
namespace main
|
||||||
|
|
||||||
|
struct Human {
|
||||||
|
name: cstring
|
||||||
|
}
|
||||||
|
|
||||||
export func main(args: []cstring): i64 {
|
export func main(args: []cstring): i64 {
|
||||||
let x: cstring
|
let human: Human
|
||||||
|
|
||||||
x = args[0]
|
human = alloc Human {
|
||||||
|
name = "test"
|
||||||
|
}
|
||||||
|
|
||||||
c::puts(x)
|
c::puts(human.name)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,57 +5,8 @@
|
|||||||
.text
|
.text
|
||||||
.globl _start
|
.globl _start
|
||||||
_start:
|
_start:
|
||||||
mov rdi, [rsp] # rdi = argc
|
|
||||||
|
|
||||||
# Calculate the size of the array
|
|
||||||
mov rax, rdi # Start with argc
|
|
||||||
shl rax, 3 # Multiply argc by 8
|
|
||||||
add rax, 8 # Add space for the array size
|
|
||||||
|
|
||||||
# Allocate array size on the stack (aligned to 16 bytes)
|
|
||||||
add rax, 15
|
|
||||||
and rax, -16
|
|
||||||
sub rsp, rax
|
|
||||||
|
|
||||||
# Store number of elements at the start of the array
|
|
||||||
mov [rsp], rdi
|
|
||||||
|
|
||||||
mov rcx, rdi # rcx = loop counter
|
|
||||||
lea rsi, [rsp + rax + 8] # rsi = argv[0]
|
|
||||||
lea rdi, [rsp + 8] # rdi = destination_array[0]
|
|
||||||
|
|
||||||
convert_loop:
|
|
||||||
test rcx, rcx
|
|
||||||
jz done_converting
|
|
||||||
|
|
||||||
# Convert current cstring using nub_cstring_to_string
|
|
||||||
push rcx # Save loop counter
|
|
||||||
push rsi # Save argv[i]
|
|
||||||
push rdi # Save destination_array[i]
|
|
||||||
|
|
||||||
mov rdi, [rsi] # Load current argv[i] (cstring)
|
|
||||||
call nub_cstring_to_string
|
|
||||||
|
|
||||||
pop rdi # Restore destination pointer
|
|
||||||
pop rsi # Restore argv pointer
|
|
||||||
pop rcx # Restore loop counter
|
|
||||||
|
|
||||||
test rax, rax
|
|
||||||
jz conversion_failed
|
|
||||||
|
|
||||||
# Store converted string pointer in our array
|
|
||||||
mov [rdi], rax # Store converted string pointer
|
|
||||||
add rdi, 8 # Move to next destination_array entry
|
|
||||||
add rsi, 8 # Move to next argv entry
|
|
||||||
dec rcx # Decrement counter
|
|
||||||
jmp convert_loop
|
|
||||||
|
|
||||||
done_converting:
|
|
||||||
mov rdi, rsp
|
mov rdi, rsp
|
||||||
call main
|
call main
|
||||||
mov rdi, rax
|
mov rdi, rax
|
||||||
mov rax, SYS_EXIT
|
mov rax, SYS_EXIT
|
||||||
syscall
|
syscall
|
||||||
|
|
||||||
conversion_failed:
|
|
||||||
call nub_panic
|
|
||||||
|
|||||||
@@ -494,12 +494,12 @@ public static class QBEGenerator
|
|||||||
case StatementExpressionNode statementExpression:
|
case StatementExpressionNode statementExpression:
|
||||||
GenerateExpression(statementExpression.Expression);
|
GenerateExpression(statementExpression.Expression);
|
||||||
break;
|
break;
|
||||||
case VariableAssignmentNode variableAssignment:
|
|
||||||
GenerateVariableAssignment(variableAssignment);
|
|
||||||
break;
|
|
||||||
case VariableDeclarationNode variableDeclaration:
|
case VariableDeclarationNode variableDeclaration:
|
||||||
GenerateVariableDeclaration(variableDeclaration);
|
GenerateVariableDeclaration(variableDeclaration);
|
||||||
break;
|
break;
|
||||||
|
case VariableAssignmentNode variableAssignment:
|
||||||
|
GenerateVariableAssignment(variableAssignment);
|
||||||
|
break;
|
||||||
case WhileNode whileStatement:
|
case WhileNode whileStatement:
|
||||||
GenerateWhile(whileStatement);
|
GenerateWhile(whileStatement);
|
||||||
break;
|
break;
|
||||||
@@ -762,26 +762,26 @@ public static class QBEGenerator
|
|||||||
|
|
||||||
private static void GenerateArrayBoundsCheck(string array, string index)
|
private static void GenerateArrayBoundsCheck(string array, string index)
|
||||||
{
|
{
|
||||||
// var countName = VarName();
|
var countName = VarName();
|
||||||
// _builder.AppendLine($" {countName} =l loadl {array}");
|
_builder.AppendLine($" {countName} =l loadl {array}");
|
||||||
//
|
|
||||||
// var isNegativeName = VarName();
|
var isNegativeName = VarName();
|
||||||
// _builder.AppendLine($" {isNegativeName} =w csltl {index}, 0");
|
_builder.AppendLine($" {isNegativeName} =w csltl {index}, 0");
|
||||||
//
|
|
||||||
// var isOobName = VarName();
|
var isOobName = VarName();
|
||||||
// _builder.AppendLine($" {isOobName} =w csgel {index}, {countName}");
|
_builder.AppendLine($" {isOobName} =w csgel {index}, {countName}");
|
||||||
//
|
|
||||||
// var anyOobName = VarName();
|
var anyOobName = VarName();
|
||||||
// _builder.AppendLine($" {anyOobName} =w or {isNegativeName}, {isOobName}");
|
_builder.AppendLine($" {anyOobName} =w or {isNegativeName}, {isOobName}");
|
||||||
//
|
|
||||||
// var oobLabel = LabelName();
|
var oobLabel = LabelName();
|
||||||
// var notOobLabel = LabelName();
|
var notOobLabel = LabelName();
|
||||||
// _builder.AppendLine($" jnz {anyOobName}, {oobLabel}, {notOobLabel}");
|
_builder.AppendLine($" jnz {anyOobName}, {oobLabel}, {notOobLabel}");
|
||||||
//
|
|
||||||
// _builder.AppendLine(oobLabel);
|
_builder.AppendLine(oobLabel);
|
||||||
// _builder.AppendLine($" call $nub_panic_array_oob()");
|
_builder.AppendLine($" call $nub_panic_array_oob()");
|
||||||
//
|
|
||||||
// _builder.AppendLine(notOobLabel);
|
_builder.AppendLine(notOobLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GenerateArrayInitializer(ArrayInitializerNode arrayInitializer)
|
private static string GenerateArrayInitializer(ArrayInitializerNode arrayInitializer)
|
||||||
@@ -1199,20 +1199,13 @@ public static class QBEGenerator
|
|||||||
var item = GenerateExpression(memberAccess.Expression);
|
var item = GenerateExpression(memberAccess.Expression);
|
||||||
switch (memberAccess.Expression.Type)
|
switch (memberAccess.Expression.Type)
|
||||||
{
|
{
|
||||||
case NubArrayType arrayType:
|
case NubArrayType:
|
||||||
{
|
{
|
||||||
if (memberAccess.Member == "count")
|
if (memberAccess.Member == "count")
|
||||||
{
|
{
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arrayType.ElementType is NubPrimitiveType { Kind: PrimitiveTypeKind.U8 } && memberAccess.Member == "cstring")
|
|
||||||
{
|
|
||||||
var result = VarName();
|
|
||||||
_builder.AppendLine($" {result} =l call $nub_string_to_cstring(l {item})");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new UnreachableException(nameof(memberAccess.Member));
|
throw new UnreachableException(nameof(memberAccess.Member));
|
||||||
}
|
}
|
||||||
case NubStructType structType:
|
case NubStructType structType:
|
||||||
|
|||||||
@@ -359,7 +359,7 @@ public static class TypeChecker
|
|||||||
{
|
{
|
||||||
LiteralKind.Integer => NubPrimitiveType.I64,
|
LiteralKind.Integer => NubPrimitiveType.I64,
|
||||||
LiteralKind.Float => NubPrimitiveType.F64,
|
LiteralKind.Float => NubPrimitiveType.F64,
|
||||||
LiteralKind.String => new NubArrayType(NubPrimitiveType.U8),
|
LiteralKind.String => new NubCStringType(),
|
||||||
LiteralKind.Bool => NubPrimitiveType.Bool,
|
LiteralKind.Bool => NubPrimitiveType.Bool,
|
||||||
_ => throw new ArgumentOutOfRangeException()
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
};
|
};
|
||||||
@@ -563,18 +563,13 @@ public static class TypeChecker
|
|||||||
|
|
||||||
switch (expressionType)
|
switch (expressionType)
|
||||||
{
|
{
|
||||||
case NubArrayType arrayType:
|
case NubArrayType:
|
||||||
{
|
{
|
||||||
if (memberAccess.Member == "count")
|
if (memberAccess.Member == "count")
|
||||||
{
|
{
|
||||||
return NubPrimitiveType.I64;
|
return NubPrimitiveType.I64;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arrayType.ElementType is NubPrimitiveType { Kind: PrimitiveTypeKind.U8 } && memberAccess.Member == "cstring")
|
|
||||||
{
|
|
||||||
return new NubCStringType();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NubStructType structType:
|
case NubStructType structType:
|
||||||
|
|||||||
Reference in New Issue
Block a user