Skip to content

Commit a6f7ba5

Browse files
authored
Merge pull request #9 from oralang/standardlib
Standardlib
2 parents 624c6f0 + db0de08 commit a6f7ba5

File tree

16 files changed

+1856
-143
lines changed

16 files changed

+1856
-143
lines changed

ora-example/erc20.ora

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Minimal ERC20 Token Implementation in Ora
2+
// Using only currently available features
3+
4+
contract SimpleToken {
5+
// Storage
6+
storage totalSupply: u256;
7+
storage balances: map[address, u256];
8+
storage allowances: doublemap[address, address, u256];
9+
10+
// Initialize with supply (call once at deployment)
11+
pub fn initialize(initialSupply: u256) -> bool {
12+
let deployer = std.msg.sender();
13+
totalSupply = initialSupply;
14+
balances[deployer] = initialSupply;
15+
return true;
16+
}
17+
18+
// Get total supply
19+
pub fn getTotalSupply() -> u256 {
20+
return totalSupply;
21+
}
22+
23+
// Get balance of an account
24+
pub fn balanceOf(account: address) -> u256 {
25+
return balances[account];
26+
}
27+
28+
// Transfer tokens from sender to recipient
29+
pub fn transfer(recipient: address, amount: u256) -> bool {
30+
let sender = std.msg.sender();
31+
let senderBalance = balances[sender];
32+
33+
// Simple checks without require
34+
if (senderBalance < amount) {
35+
return false;
36+
}
37+
38+
if (recipient == std.constants.ZERO_ADDRESS) {
39+
return false;
40+
}
41+
42+
// Perform transfer
43+
balances[sender] = senderBalance - amount;
44+
let recipientBalance = balances[recipient];
45+
balances[recipient] = recipientBalance + amount;
46+
47+
return true;
48+
}
49+
50+
// Approve spender to spend tokens
51+
pub fn approve(spender: address, amount: u256) -> bool {
52+
let owner = std.msg.sender();
53+
54+
if (spender == std.constants.ZERO_ADDRESS) {
55+
return false;
56+
}
57+
58+
allowances[owner][spender] = amount;
59+
return true;
60+
}
61+
62+
// Get allowance
63+
pub fn allowance(owner: address, spender: address) -> u256 {
64+
return allowances[owner][spender];
65+
}
66+
67+
// Transfer from one address to another using allowance
68+
pub fn transferFrom(sender: address, recipient: address, amount: u256) -> bool {
69+
let spender = std.msg.sender();
70+
71+
let currentAllowance = allowances[sender][spender];
72+
if (currentAllowance < amount) {
73+
return false;
74+
}
75+
76+
let senderBalance = balances[sender];
77+
if (senderBalance < amount) {
78+
return false;
79+
}
80+
81+
if (recipient == std.constants.ZERO_ADDRESS) {
82+
return false;
83+
}
84+
85+
// Update allowance
86+
allowances[sender][spender] = currentAllowance - amount;
87+
88+
// Perform transfer
89+
balances[sender] = senderBalance - amount;
90+
let recipientBalance = balances[recipient];
91+
balances[recipient] = recipientBalance + amount;
92+
93+
return true;
94+
}
95+
}
96+

ora-example/test_std_builtins.ora

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Test contract for standard library builtins
2+
contract StdBuiltinsTest {
3+
storage lastCaller: address;
4+
storage lastTimestamp: u256;
5+
6+
// Test basic builtin usage
7+
pub fn recordInfo() -> bool {
8+
let caller = std.msg.sender();
9+
let time = std.block.timestamp();
10+
11+
lastCaller = caller;
12+
lastTimestamp = time;
13+
14+
return true;
15+
}
16+
17+
// Test block.timestamp
18+
pub fn getTimestamp() -> u256 {
19+
return std.block.timestamp();
20+
}
21+
22+
// Test block.number
23+
pub fn getBlockNumber() -> u256 {
24+
return std.block.number();
25+
}
26+
27+
// Test block.coinbase
28+
pub fn getCoinbase() -> address {
29+
return std.block.coinbase();
30+
}
31+
32+
// Test transaction.sender
33+
pub fn getOrigin() -> address {
34+
return std.transaction.sender();
35+
}
36+
37+
// Test msg.sender
38+
pub fn getSender() -> address {
39+
return std.msg.sender();
40+
}
41+
42+
// Test msg.value
43+
pub fn getValue() -> u256 {
44+
return std.msg.value();
45+
}
46+
47+
// Test constant ZERO_ADDRESS
48+
pub fn getZeroAddress() -> address {
49+
return std.constants.ZERO_ADDRESS;
50+
}
51+
52+
// Test constant U256_MAX
53+
pub fn getMaxU256() -> u256 {
54+
return std.constants.U256_MAX;
55+
}
56+
}
57+

src/mlir/declarations.zig

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub const DeclarationLowerer = struct {
4646
error_handler: ?*const @import("error_handling.zig").ErrorHandler,
4747
ora_dialect: *@import("dialect.zig").OraDialect,
4848
symbol_table: ?*@import("lower.zig").SymbolTable = null,
49+
builtin_registry: ?*const lib.semantics.builtins.BuiltinRegistry = null,
4950

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

80-
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 {
81+
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 {
8182
return .{
8283
.ctx = ctx,
8384
.type_mapper = type_mapper,
8485
.locations = locations,
8586
.error_handler = error_handler,
8687
.ora_dialect = ora_dialect,
8788
.symbol_table = symbol_table,
89+
.builtin_registry = builtin_registry,
8890
};
8991
}
9092

@@ -784,7 +786,7 @@ pub const DeclarationLowerer = struct {
784786

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

790792
return c.mlirOperationCreate(&state);
@@ -917,15 +919,15 @@ pub const DeclarationLowerer = struct {
917919
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 {
918920
// Create a statement lowerer for this function
919921
const const_local_var_map = if (local_var_map) |lvm| @as(*const LocalVarMap, lvm) else null;
920-
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);
922+
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);
921923

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

928-
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);
930+
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);
929931

930932
// Lower the function body
931933
try stmt_lowerer.lowerBlockBody(func.body, block);
@@ -934,7 +936,7 @@ pub const DeclarationLowerer = struct {
934936
/// Lower requires clauses as precondition assertions with enhanced verification metadata (Requirements 6.4)
935937
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 {
936938
const const_local_var_map = if (local_var_map) |lvm| @as(*const LocalVarMap, lvm) else null;
937-
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);
939+
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);
938940

939941
for (requires_clauses, 0..) |clause, i| {
940942
// Lower the requires expression
@@ -986,7 +988,7 @@ pub const DeclarationLowerer = struct {
986988
/// Lower ensures clauses as postcondition assertions with enhanced verification metadata (Requirements 6.5)
987989
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 {
988990
const const_local_var_map = if (local_var_map) |lvm| @as(*const LocalVarMap, lvm) else null;
989-
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);
991+
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);
990992

991993
for (ensures_clauses, 0..) |clause, i| {
992994
// Lower the ensures expression

0 commit comments

Comments
 (0)