Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions ora-example/erc20.ora
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Minimal ERC20 Token Implementation in Ora
// Using only currently available features

contract SimpleToken {
// Storage
storage totalSupply: u256;
storage balances: map[address, u256];
storage allowances: doublemap[address, address, u256];

// Initialize with supply (call once at deployment)
pub fn initialize(initialSupply: u256) -> bool {
let deployer = std.msg.sender();
totalSupply = initialSupply;
balances[deployer] = initialSupply;
return true;
}

// Get total supply
pub fn getTotalSupply() -> u256 {
return totalSupply;
}

// Get balance of an account
pub fn balanceOf(account: address) -> u256 {
return balances[account];
}

// Transfer tokens from sender to recipient
pub fn transfer(recipient: address, amount: u256) -> bool {
let sender = std.msg.sender();
let senderBalance = balances[sender];

// Simple checks without require
if (senderBalance < amount) {
return false;
}

if (recipient == std.constants.ZERO_ADDRESS) {
return false;
}

// Perform transfer
balances[sender] = senderBalance - amount;
let recipientBalance = balances[recipient];
balances[recipient] = recipientBalance + amount;

return true;
}

// Approve spender to spend tokens
pub fn approve(spender: address, amount: u256) -> bool {
let owner = std.msg.sender();

if (spender == std.constants.ZERO_ADDRESS) {
return false;
}

allowances[owner][spender] = amount;
return true;
}

// Get allowance
pub fn allowance(owner: address, spender: address) -> u256 {
return allowances[owner][spender];
}

// Transfer from one address to another using allowance
pub fn transferFrom(sender: address, recipient: address, amount: u256) -> bool {
let spender = std.msg.sender();

let currentAllowance = allowances[sender][spender];
if (currentAllowance < amount) {
return false;
}

let senderBalance = balances[sender];
if (senderBalance < amount) {
return false;
}

if (recipient == std.constants.ZERO_ADDRESS) {
return false;
}

// Update allowance
allowances[sender][spender] = currentAllowance - amount;

// Perform transfer
balances[sender] = senderBalance - amount;
let recipientBalance = balances[recipient];
balances[recipient] = recipientBalance + amount;

return true;
}
}

57 changes: 57 additions & 0 deletions ora-example/test_std_builtins.ora
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Test contract for standard library builtins
contract StdBuiltinsTest {
storage lastCaller: address;
storage lastTimestamp: u256;

// Test basic builtin usage
pub fn recordInfo() -> bool {
let caller = std.msg.sender();
let time = std.block.timestamp();

lastCaller = caller;
lastTimestamp = time;

return true;
}

// Test block.timestamp
pub fn getTimestamp() -> u256 {
return std.block.timestamp();
}

// Test block.number
pub fn getBlockNumber() -> u256 {
return std.block.number();
}

// Test block.coinbase
pub fn getCoinbase() -> address {
return std.block.coinbase();
}

// Test transaction.sender
pub fn getOrigin() -> address {
return std.transaction.sender();
}

// Test msg.sender
pub fn getSender() -> address {
return std.msg.sender();
}

// Test msg.value
pub fn getValue() -> u256 {
return std.msg.value();
}

// Test constant ZERO_ADDRESS
pub fn getZeroAddress() -> address {
return std.constants.ZERO_ADDRESS;
}

// Test constant U256_MAX
pub fn getMaxU256() -> u256 {
return std.constants.U256_MAX;
}
}

14 changes: 8 additions & 6 deletions src/mlir/declarations.zig
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub const DeclarationLowerer = struct {
error_handler: ?*const @import("error_handling.zig").ErrorHandler,
ora_dialect: *@import("dialect.zig").OraDialect,
symbol_table: ?*@import("lower.zig").SymbolTable = null,
builtin_registry: ?*const lib.semantics.builtins.BuiltinRegistry = null,

pub fn init(ctx: c.MlirContext, type_mapper: *const TypeMapper, locations: LocationTracker, ora_dialect: *@import("dialect.zig").OraDialect) DeclarationLowerer {
return .{
Expand Down Expand Up @@ -77,14 +78,15 @@ pub const DeclarationLowerer = struct {
};
}

pub fn withErrorHandlerAndDialectAndSymbolTable(ctx: c.MlirContext, type_mapper: *const TypeMapper, locations: LocationTracker, error_handler: *const @import("error_handling.zig").ErrorHandler, ora_dialect: *@import("dialect.zig").OraDialect, symbol_table: *@import("lower.zig").SymbolTable) DeclarationLowerer {
pub fn withErrorHandlerAndDialectAndSymbolTable(ctx: c.MlirContext, type_mapper: *const TypeMapper, locations: LocationTracker, error_handler: *const @import("error_handling.zig").ErrorHandler, ora_dialect: *@import("dialect.zig").OraDialect, symbol_table: *@import("lower.zig").SymbolTable, builtin_registry: ?*const lib.semantics.builtins.BuiltinRegistry) DeclarationLowerer {
return .{
.ctx = ctx,
.type_mapper = type_mapper,
.locations = locations,
.error_handler = error_handler,
.ora_dialect = ora_dialect,
.symbol_table = symbol_table,
.builtin_registry = builtin_registry,
};
}

Expand Down Expand Up @@ -784,7 +786,7 @@ pub const DeclarationLowerer = struct {

// Lower the constant value expression
// Create a temporary expression lowerer to lower the constant value
const expr_lowerer = ExpressionLowerer.init(self.ctx, block, self.type_mapper, null, null, null, null, self.locations, self.ora_dialect);
const expr_lowerer = ExpressionLowerer.init(self.ctx, block, self.type_mapper, null, null, null, null, self.builtin_registry, self.locations, self.ora_dialect);
_ = expr_lowerer.lowerExpression(const_decl.value);

return c.mlirOperationCreate(&state);
Expand Down Expand Up @@ -917,15 +919,15 @@ pub const DeclarationLowerer = struct {
fn lowerFunctionBody(self: *const DeclarationLowerer, func: *const lib.FunctionNode, block: c.MlirBlock, param_map: *const ParamMap, storage_map: ?*const StorageMap, local_var_map: ?*LocalVarMap) LoweringError!void {
// Create a statement lowerer for this function
const const_local_var_map = if (local_var_map) |lvm| @as(*const LocalVarMap, lvm) else null;
const expr_lowerer = ExpressionLowerer.init(self.ctx, block, self.type_mapper, param_map, storage_map, const_local_var_map, self.symbol_table, self.locations, self.ora_dialect);
const expr_lowerer = ExpressionLowerer.init(self.ctx, block, self.type_mapper, param_map, storage_map, const_local_var_map, self.symbol_table, self.builtin_registry, self.locations, self.ora_dialect);

// Get the function's return type
const function_return_type = if (func.return_type_info) |ret_info|
self.type_mapper.toMlirType(ret_info)
else
null;

const stmt_lowerer = StatementLowerer.init(self.ctx, block, self.type_mapper, &expr_lowerer, param_map, storage_map, local_var_map, self.locations, self.symbol_table, std.heap.page_allocator, function_return_type, self.ora_dialect);
const stmt_lowerer = StatementLowerer.init(self.ctx, block, self.type_mapper, &expr_lowerer, param_map, storage_map, local_var_map, self.locations, self.symbol_table, self.builtin_registry, std.heap.page_allocator, function_return_type, self.ora_dialect);

// Lower the function body
try stmt_lowerer.lowerBlockBody(func.body, block);
Expand All @@ -934,7 +936,7 @@ pub const DeclarationLowerer = struct {
/// Lower requires clauses as precondition assertions with enhanced verification metadata (Requirements 6.4)
fn lowerRequiresClauses(self: *const DeclarationLowerer, requires_clauses: []*lib.ast.Expressions.ExprNode, block: c.MlirBlock, param_map: *const ParamMap, storage_map: ?*const StorageMap, local_var_map: ?*LocalVarMap) LoweringError!void {
const const_local_var_map = if (local_var_map) |lvm| @as(*const LocalVarMap, lvm) else null;
const expr_lowerer = ExpressionLowerer.init(self.ctx, block, self.type_mapper, param_map, storage_map, const_local_var_map, self.symbol_table, self.locations, self.ora_dialect);
const expr_lowerer = ExpressionLowerer.init(self.ctx, block, self.type_mapper, param_map, storage_map, const_local_var_map, self.symbol_table, self.builtin_registry, self.locations, self.ora_dialect);

for (requires_clauses, 0..) |clause, i| {
// Lower the requires expression
Expand Down Expand Up @@ -986,7 +988,7 @@ pub const DeclarationLowerer = struct {
/// Lower ensures clauses as postcondition assertions with enhanced verification metadata (Requirements 6.5)
fn lowerEnsuresClauses(self: *const DeclarationLowerer, ensures_clauses: []*lib.ast.Expressions.ExprNode, block: c.MlirBlock, param_map: *const ParamMap, storage_map: ?*const StorageMap, local_var_map: ?*LocalVarMap) LoweringError!void {
const const_local_var_map = if (local_var_map) |lvm| @as(*const LocalVarMap, lvm) else null;
const expr_lowerer = ExpressionLowerer.init(self.ctx, block, self.type_mapper, param_map, storage_map, const_local_var_map, self.symbol_table, self.locations, self.ora_dialect);
const expr_lowerer = ExpressionLowerer.init(self.ctx, block, self.type_mapper, param_map, storage_map, const_local_var_map, self.symbol_table, self.builtin_registry, self.locations, self.ora_dialect);

for (ensures_clauses, 0..) |clause, i| {
// Lower the ensures expression
Expand Down
Loading
Loading