├── src ├── test │ ├── pacode │ │ ├── 520_const_LRnum_err.pa │ │ ├── 539_not_var_sytax_err.pa │ │ ├── 557_unsupported_err2.pa │ │ ├── 501_dupvar_err.pa │ │ ├── 530_arrlit_type_err4.pa │ │ ├── 546_const_exp_err.pa │ │ ├── 556_unsupported_err.pa │ │ ├── 502_undeffunc_err.pa │ │ ├── 522_cantuse_index_err.pa │ │ ├── 523_varinitLRnum_err.pa │ │ ├── 534_ambiguous_type_err.pa │ │ ├── 536_varinit_type_err2.pa │ │ ├── 538_var_difftypes_err.pa │ │ ├── 565_unsupported_err3.pa │ │ ├── 597_increment_err.pa │ │ ├── 598_increment_err2.pa │ │ ├── 503_undefvar_err.pa │ │ ├── 525_undeftype_err.pa │ │ ├── 527_arrlit_type_err.pa │ │ ├── 528_arrlit_type_err2.pa │ │ ├── 537_dupinfervar_err.pa │ │ ├── 540_noinit_autotype_err.pa │ │ ├── 554_arrlit_type_err6.pa │ │ ├── 582_nomember_err2.pa │ │ ├── 593_incompatiref_err.pa │ │ ├── 594_refinit_err.pa │ │ ├── 609_nosizearray_alloc_err.pa │ │ ├── 507_toplvstmt_err.pa │ │ ├── 513_asgnLRnum_err.pa │ │ ├── 526_arraysize_noint_err.pa │ │ ├── 541_varinit_type_err3.pa │ │ ├── 545_undefconst_err.pa │ │ ├── 553_arrlit_type_err5.pa │ │ ├── 579_dupinfervar_err2.pa │ │ ├── 592_cantcopytype_err.pa │ │ ├── 524_flo_mod_err.pa │ │ ├── 542_asgnLRnum_err2.pa │ │ ├── 550_const_assign_err.pa │ │ ├── 561_arrval_type_err4.pa │ │ ├── 567_unsupported_err4.pa │ │ ├── 580_dupinfervar_err3.pa │ │ ├── 585_needinit_err.pa │ │ ├── 586_cantusemove_err6.pa │ │ ├── 587_arrind_token_err.pa │ │ ├── 588_dynamic2ref_err.pa │ │ ├── 595_roassign_err.pa │ │ ├── 518_invalid_constuse_err.pa │ │ ├── 529_arrlit_type_err3.pa │ │ ├── 532_func_retval_err2.pa │ │ ├── 535_varinit_type_err.pa │ │ ├── 551_constarr_mv_err2.pa │ │ ├── 559_arrval_type_err2.pa │ │ ├── 562_arrval_type_err5.pa │ │ ├── 572_unsupported_err3.pa │ │ ├── 584_cantusemove_err5.pa │ │ ├── 500_syntax_err.pa │ │ ├── 547_constarr_exp_err.pa │ │ ├── 558_arrval_type_err.pa │ │ ├── 563_arrval_type_err6.pa │ │ ├── 517_invalid_constval_err.pa │ │ ├── 569_break_notinloop_err.pa │ │ ├── 571_placehold_no_param_err.pa │ │ ├── 504_copyfreevar_err.pa │ │ ├── 510_invalidret1_err.pa │ │ ├── 516_duplicate_const_err.pa │ │ ├── 549_constarr_mv_err.pa │ │ ├── 555_arrlit_type_err7.pa │ │ ├── 599_anysize_arr_err.pa │ │ ├── 506_assigntype_err.pa │ │ ├── 511_invalidret2_err.pa │ │ ├── 531_func_retval_err.pa │ │ ├── 533_func_retval_err3.pa │ │ ├── 570_continue_notinloop_err.pa │ │ ├── 583_structtype_err2.pa │ │ ├── 589_structinit_err.pa │ │ ├── 596_incompatiref_err2.pa │ │ ├── 508_needretarg_err.pa │ │ ├── 560_arrval_type_err3.pa │ │ ├── 566_copyfreevar_err4.pa │ │ ├── 576_nomember_err.pa │ │ ├── 578_structtype_err.pa │ │ ├── 512_invalidret3_err.pa │ │ ├── 521_asgn_novalue_err.pa │ │ ├── 564_arrval_type_err7.pa │ │ ├── 591_externdup_err2.pa │ │ ├── 608_fixedarray_typecmp_err9.pa │ │ ├── 515_undefchainfunc_err.pa │ │ ├── 568_voiditem_err.pa │ │ ├── 607_fixedarray_typecmp_err8.pa │ │ ├── 601_fixedarray_typecmp_err2.pa │ │ ├── 603_fixedarray_typecmp_err4.pa │ │ ├── 548_constarr_exp_err2.pa │ │ ├── 552_ambigfunc_err2.pa │ │ ├── 602_fixedarray_typecmp_err3.pa │ │ ├── 604_fixedarray_typecmp_err5.pa │ │ ├── 509_needret_err.pa │ │ ├── 519_duplicate_func_err.pa │ │ ├── 543_copyfreevar_err2.pa │ │ ├── 600_fixedarray_typecmp_err1.pa │ │ ├── 514_cantusemove_err.pa │ │ ├── 581_duptype_err.pa │ │ ├── 605_fixedarray_typecmp_err6.pa │ │ ├── 606_fixedarray_typecmp_err7.pa │ │ ├── 001_helloworld.pa │ │ ├── 544_copyfreevar_err3.pa │ │ ├── 574_cantusemove_err3.pa │ │ ├── 575_copy2rovar_err.pa │ │ ├── 505_ambigfunc_err.pa │ │ ├── 590_externdup_err.pa │ │ ├── 036_methodcall.pa │ │ ├── 573_cantusemove_err2.pa │ │ ├── 003_varbyte.pa │ │ ├── 577_cantusemove_err4.pa │ │ ├── 000_temp.pa │ │ ├── 014_const.pa │ │ ├── 102_lsm.pa │ │ ├── 012_overload.pa │ │ ├── 018_floarr.pa │ │ ├── 034_increment.pa │ │ ├── 029_typealias.pa │ │ ├── 022_type_inference.pa │ │ ├── 032_ptrptr.pa │ │ ├── 038_calcopti.pa │ │ ├── 002_varint64.pa │ │ ├── 004_regalloc.pa │ │ ├── 100_qsort.pa │ │ ├── 024_default_arg.pa │ │ ├── 021_arr_size_infer.pa │ │ ├── 033_prireference.pa │ │ ├── 007_whiletest.pa │ │ ├── 023_const_array.pa │ │ ├── 026_arrarr_value.pa │ │ ├── 101_8queen.pa │ │ ├── 035_structonstack.pa │ │ ├── 008_iftest.pa │ │ ├── 005_intpromotion.pa │ │ ├── 013_chaincall.pa │ │ ├── 037_directobj_arr.pa │ │ ├── 039_dirctallocmember.pa │ │ ├── 015_assignment2.pa │ │ ├── 030_reference.pa │ │ ├── 006_intarray.pa │ │ ├── 010_arrarray.pa │ │ ├── 020_arrlit.pa │ │ ├── 027_ccall.pa │ │ ├── 025_array_value.pa │ │ ├── 011_assignment.pa │ │ ├── 016_varflo.pa │ │ └── 028_struct.pa │ ├── gdbstart.sh │ ├── testBase.h │ ├── cuiTestBase.h │ ├── cuiTestMain.cpp │ ├── testMain.cpp │ ├── depend.inc │ ├── algorithmTest.cpp │ ├── Makefile │ ├── capi4test.c │ ├── coverage.sh │ └── cuiTestBase.cpp ├── generators │ ├── PlnX86_64RegisterSave.h │ ├── PlnX86_64CalcOptimization.h │ ├── PlnX86_64RegisterMachineImp.h │ ├── PlnX86_64DataAllocator.h │ └── PlnX86_64CalcOptimization.cpp ├── PlnModelTreeBuilder.h ├── PlnException.h ├── ast │ ├── PlnLexer.h │ ├── PlnAstMessage.h │ ├── Makefile │ ├── PlnAstMessage.cpp │ └── palanast.cpp ├── models │ ├── expressions │ │ ├── PlnReferenceValue.h │ │ ├── PlnMulOperation.h │ │ ├── PlnStructMember.h │ │ ├── PlnAssignment.h │ │ ├── PlnCmpOperation.h │ │ ├── assignitem │ │ │ ├── PlnAssignItem.h │ │ │ ├── PlnAssignPrimitiveItem.h │ │ │ ├── PlnChainAssignItem.h │ │ │ ├── arrval_imp │ │ │ │ ├── PlnAssignArrayValue_Static.h │ │ │ │ └── PlnAssignArrayValue_Var.h │ │ │ ├── PlnAssignObjectRefItem.h │ │ │ ├── PlnDstMoveObjectItem.h │ │ │ ├── PlnAssignArrayValue.h │ │ │ └── PlnDstPrimitiveItem.h │ │ ├── PlnDivOperation.h │ │ ├── PlnArrayItem.h │ │ ├── PlnClone.h │ │ ├── PlnAddOperation.h │ │ ├── PlnBoolExpression.h │ │ ├── PlnArrayValue.h │ │ ├── PlnBoolOperation.h │ │ ├── PlnFunctionCall.h │ │ ├── PlnCalcOperationUtils.h │ │ ├── PlnMemCopy.h │ │ ├── PlnReferenceValue.cpp │ │ └── PlnBoolExpression.cpp │ ├── types │ │ ├── PlnArrayValueType.h │ │ ├── PlnAliasType.h │ │ ├── PlnStructType.h │ │ └── PlnFixedArrayType.h │ ├── PlnModule.h │ ├── PlnConditionalBranch.h │ ├── PlnVariable.h │ ├── PlnLoopStatement.h │ ├── PlnStatement.h │ ├── PlnConditionalBranch.cpp │ ├── PlnExpression.h │ ├── PlnFunction.h │ ├── PlnBlock.h │ └── PlnModule.cpp ├── PlnTreeBuildHelper.h ├── PlnConstants.h ├── PlnScopeStack.cpp ├── PlnModel.h ├── PlnScopeStack.h ├── PlnMessage.h ├── PlnGenerator.cpp └── Makefile ├── .gitmodules ├── idea ├── Import.pa ├── Class.hpa ├── Helloworld.pa ├── NQueen.pa ├── String.pa ├── Error.pa ├── Statement.pa ├── ChainCall.pa ├── Array.pa ├── CCall.pa ├── Class.pa └── Function.pa ├── .gitignore ├── tools ├── loc.sh └── pa.vim ├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md └── workflows │ └── build.yml ├── Makefile ├── LICENSE ├── README.md ├── samples └── usesqlite.pa └── CODE_OF_CONDUCT.md /src/test/pacode/520_const_LRnum_err.pa: -------------------------------------------------------------------------------- 1 | const A,B = 10; 2 | -------------------------------------------------------------------------------- /src/test/pacode/539_not_var_sytax_err.pa: -------------------------------------------------------------------------------- 1 | a, b = 3, 5; 2 | -------------------------------------------------------------------------------- /src/test/pacode/557_unsupported_err2.pa: -------------------------------------------------------------------------------- 1 | aaa = "err"; 2 | -------------------------------------------------------------------------------- /src/test/pacode/501_dupvar_err.pa: -------------------------------------------------------------------------------- 1 | int32 a, b; 2 | int16 b; 3 | -------------------------------------------------------------------------------- /src/test/pacode/530_arrlit_type_err4.pa: -------------------------------------------------------------------------------- 1 | [3]int64 a = [1,2]; 2 | -------------------------------------------------------------------------------- /src/test/pacode/546_const_exp_err.pa: -------------------------------------------------------------------------------- 1 | const i = xfunc(); 2 | -------------------------------------------------------------------------------- /src/test/pacode/556_unsupported_err.pa: -------------------------------------------------------------------------------- 1 | 2 | a=[1,2,[2]]; 3 | -------------------------------------------------------------------------------- /src/test/pacode/502_undeffunc_err.pa: -------------------------------------------------------------------------------- 1 | int32 a = 35; 2 | add(a); 3 | -------------------------------------------------------------------------------- /src/test/pacode/522_cantuse_index_err.pa: -------------------------------------------------------------------------------- 1 | int32 a; 2 | 2 -> a[0]; 3 | -------------------------------------------------------------------------------- /src/test/pacode/523_varinitLRnum_err.pa: -------------------------------------------------------------------------------- 1 | int32 a, b = 3, 2, 5; 2 | -------------------------------------------------------------------------------- /src/test/pacode/534_ambiguous_type_err.pa: -------------------------------------------------------------------------------- 1 | 2 | []int64 amb_arr; 3 | -------------------------------------------------------------------------------- /src/test/pacode/536_varinit_type_err2.pa: -------------------------------------------------------------------------------- 1 | [,]int64 b = [2,3,5]; 2 | -------------------------------------------------------------------------------- /src/test/pacode/538_var_difftypes_err.pa: -------------------------------------------------------------------------------- 1 | var a, b = 1, [1,2]; 2 | -------------------------------------------------------------------------------- /src/test/pacode/565_unsupported_err3.pa: -------------------------------------------------------------------------------- 1 | i = 0; 2 | a=[1,2,[i]]; 3 | -------------------------------------------------------------------------------- /src/test/pacode/597_increment_err.pa: -------------------------------------------------------------------------------- 1 | int64 i; 2 | 3 | i+1 ++; 4 | -------------------------------------------------------------------------------- /src/test/pacode/598_increment_err2.pa: -------------------------------------------------------------------------------- 1 | [3]int64 a; 2 | 3 | a++; 4 | -------------------------------------------------------------------------------- /src/test/pacode/503_undefvar_err.pa: -------------------------------------------------------------------------------- 1 | int16 abc; 2 | 3 | 35->abcd; 4 | -------------------------------------------------------------------------------- /src/test/pacode/525_undeftype_err.pa: -------------------------------------------------------------------------------- 1 | int64 i = 10; 2 | int ii = 20; 3 | -------------------------------------------------------------------------------- /src/test/pacode/527_arrlit_type_err.pa: -------------------------------------------------------------------------------- 1 | 2 | [2][3]int64 aa = [1,2]; 3 | -------------------------------------------------------------------------------- /src/test/pacode/528_arrlit_type_err2.pa: -------------------------------------------------------------------------------- 1 | 2 | 3 | int64 a = [1,2,3]; 4 | -------------------------------------------------------------------------------- /src/test/pacode/537_dupinfervar_err.pa: -------------------------------------------------------------------------------- 1 | i = 0; 2 | j = i; 3 | i = j; 4 | -------------------------------------------------------------------------------- /src/test/pacode/540_noinit_autotype_err.pa: -------------------------------------------------------------------------------- 1 | var a, b, var c = 1, 2; 2 | -------------------------------------------------------------------------------- /src/test/pacode/554_arrlit_type_err6.pa: -------------------------------------------------------------------------------- 1 | [2,3]int64 arr = [[1,2,3],5]; 2 | -------------------------------------------------------------------------------- /src/test/pacode/582_nomember_err2.pa: -------------------------------------------------------------------------------- 1 | int32 a; 2 | 3 | 10 -> a.x; 4 | -------------------------------------------------------------------------------- /src/test/pacode/593_incompatiref_err.pa: -------------------------------------------------------------------------------- 1 | int64 i=0; 2 | @int32 ix = i; 3 | -------------------------------------------------------------------------------- /src/test/pacode/594_refinit_err.pa: -------------------------------------------------------------------------------- 1 | int64 i = 0; 2 | @int64 iz = i+1; 3 | -------------------------------------------------------------------------------- /src/test/pacode/609_nosizearray_alloc_err.pa: -------------------------------------------------------------------------------- 1 | [?,3]int32 nosizearray; 2 | -------------------------------------------------------------------------------- /src/test/pacode/507_toplvstmt_err.pa: -------------------------------------------------------------------------------- 1 | int32 a; 2 | { 3 | return a; 4 | } 5 | -------------------------------------------------------------------------------- /src/test/pacode/513_asgnLRnum_err.pa: -------------------------------------------------------------------------------- 1 | int32 a, b, c; 2 | 1, 2 -> a, b, c; 3 | -------------------------------------------------------------------------------- /src/test/pacode/526_arraysize_noint_err.pa: -------------------------------------------------------------------------------- 1 | 2 | [3.5]int64 arr = [1,2,3]; 3 | -------------------------------------------------------------------------------- /src/test/pacode/541_varinit_type_err3.pa: -------------------------------------------------------------------------------- 1 | b = [1,2,3]; 2 | [3]int32 a = b; 3 | -------------------------------------------------------------------------------- /src/test/pacode/545_undefconst_err.pa: -------------------------------------------------------------------------------- 1 | int64 i = 3; 2 | const I = i; 3 | 4 | -------------------------------------------------------------------------------- /src/test/pacode/553_arrlit_type_err5.pa: -------------------------------------------------------------------------------- 1 | [2,3,4]int64 a = [1,2,3][1,2,3]; 2 | -------------------------------------------------------------------------------- /src/test/pacode/579_dupinfervar_err2.pa: -------------------------------------------------------------------------------- 1 | i = 0; 2 | { 3 | i = 3; 4 | } 5 | -------------------------------------------------------------------------------- /src/test/pacode/592_cantcopytype_err.pa: -------------------------------------------------------------------------------- 1 | type X; 2 | X a, b; 3 | a -> b; 4 | -------------------------------------------------------------------------------- /src/test/pacode/524_flo_mod_err.pa: -------------------------------------------------------------------------------- 1 | flo32 f=3.5; 2 | flo64 d; 3 | f % 2 -> d; 4 | -------------------------------------------------------------------------------- /src/test/pacode/542_asgnLRnum_err2.pa: -------------------------------------------------------------------------------- 1 | int32 a, b; 2 | 3 | 3, 2, 1 -> a, b; 4 | -------------------------------------------------------------------------------- /src/test/pacode/550_const_assign_err.pa: -------------------------------------------------------------------------------- 1 | const A = 10; 2 | 3 | 10 -> A; 4 | 5 | -------------------------------------------------------------------------------- /src/test/pacode/561_arrval_type_err4.pa: -------------------------------------------------------------------------------- 1 | i = 12; 2 | [3]int64 a = [1*i,2]; 3 | 4 | -------------------------------------------------------------------------------- /src/test/pacode/567_unsupported_err4.pa: -------------------------------------------------------------------------------- 1 | z = [[1,2,3][4,5,6], 11, [21,22,23]]; 2 | -------------------------------------------------------------------------------- /src/test/pacode/580_dupinfervar_err3.pa: -------------------------------------------------------------------------------- 1 | const i = 10; 2 | { 3 | i = 10; 4 | } 5 | -------------------------------------------------------------------------------- /src/test/pacode/585_needinit_err.pa: -------------------------------------------------------------------------------- 1 | @[3]int32 a = [1,2,3]; 2 | @[3]int32 b; 3 | -------------------------------------------------------------------------------- /src/test/pacode/586_cantusemove_err6.pa: -------------------------------------------------------------------------------- 1 | [32]int32 a; 2 | [?]int32 b <<= a; 3 | 4 | -------------------------------------------------------------------------------- /src/test/pacode/587_arrind_token_err.pa: -------------------------------------------------------------------------------- 1 | [10]int64 arr; 2 | 3 | 3 -> arr[?]; 4 | -------------------------------------------------------------------------------- /src/test/pacode/588_dynamic2ref_err.pa: -------------------------------------------------------------------------------- 1 | @[2][10]byte x = ["123452","acc"]; 2 | 3 | -------------------------------------------------------------------------------- /src/test/pacode/595_roassign_err.pa: -------------------------------------------------------------------------------- 1 | i=0; 2 | @int64 ix = i; 3 | 10 -> ix; 4 | 5 | -------------------------------------------------------------------------------- /src/test/pacode/518_invalid_constuse_err.pa: -------------------------------------------------------------------------------- 1 | const N = 10; 2 | 3 | int32 n = N[3]; 4 | -------------------------------------------------------------------------------- /src/test/pacode/529_arrlit_type_err3.pa: -------------------------------------------------------------------------------- 1 | [2,3]int64 a 2 | = [1,2,3] 3 | [1,2]; 4 | -------------------------------------------------------------------------------- /src/test/pacode/532_func_retval_err2.pa: -------------------------------------------------------------------------------- 1 | func err_func(int64 a) -> [3]int64 a 2 | { } 3 | -------------------------------------------------------------------------------- /src/test/pacode/535_varinit_type_err.pa: -------------------------------------------------------------------------------- 1 | int64 i; 2 | []int64 a = [2,3,5][4,5,6]; 3 | -------------------------------------------------------------------------------- /src/test/pacode/551_constarr_mv_err2.pa: -------------------------------------------------------------------------------- 1 | arr = [1,2,3]; 2 | 3 | [4,5,6] ->> arr; 4 | -------------------------------------------------------------------------------- /src/test/pacode/559_arrval_type_err2.pa: -------------------------------------------------------------------------------- 1 | i = 12; 2 | int64 a = [i, i+1, 12]; 3 | 4 | -------------------------------------------------------------------------------- /src/test/pacode/562_arrval_type_err5.pa: -------------------------------------------------------------------------------- 1 | i = 12; 2 | [2,3,4]int64 a = [1,2,3][1,2,i]; 3 | -------------------------------------------------------------------------------- /src/test/pacode/572_unsupported_err3.pa: -------------------------------------------------------------------------------- 1 | func notsuppot_va(int32 n, ...) 2 | { 3 | } 4 | -------------------------------------------------------------------------------- /src/test/pacode/584_cantusemove_err5.pa: -------------------------------------------------------------------------------- 1 | [3]int32 a; 2 | 3 | @[3]int32 b <<= a; 4 | 5 | -------------------------------------------------------------------------------- /src/test/gdbstart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | rm core 3 | ./tester 4 | gdb tester core 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/test/pacode/500_syntax_err.pa: -------------------------------------------------------------------------------- 1 | ccall printf(); 2 | 3 | int32 a 4 | printf(""); 5 | 6 | -------------------------------------------------------------------------------- /src/test/pacode/547_constarr_exp_err.pa: -------------------------------------------------------------------------------- 1 | int32 i=0; 2 | { 3 | const arr = [3, i]; 4 | } 5 | -------------------------------------------------------------------------------- /src/test/pacode/558_arrval_type_err.pa: -------------------------------------------------------------------------------- 1 | int64 i = 10; 2 | 3 | [2,3]int64 arr = [i,i+1]; 4 | -------------------------------------------------------------------------------- /src/test/pacode/563_arrval_type_err6.pa: -------------------------------------------------------------------------------- 1 | i = 32; 2 | [2,3]int64 arr = [[1,i,3],5]; 3 | 4 | -------------------------------------------------------------------------------- /src/test/pacode/517_invalid_constval_err.pa: -------------------------------------------------------------------------------- 1 | int32 n = 10; 2 | { 3 | const N = n * 10; 4 | } 5 | -------------------------------------------------------------------------------- /src/test/pacode/569_break_notinloop_err.pa: -------------------------------------------------------------------------------- 1 | func test() 2 | { 3 | a = 1; 4 | break; 5 | } 6 | -------------------------------------------------------------------------------- /src/test/pacode/571_placehold_no_param_err.pa: -------------------------------------------------------------------------------- 1 | ccall cfunc(@, int64 a, @, int32 b => int64 b); 2 | -------------------------------------------------------------------------------- /src/test/pacode/504_copyfreevar_err.pa: -------------------------------------------------------------------------------- 1 | [3]int32 arr, arr2; 2 | 3 | arr2 ->> arr; 4 | arr -> arr2; 5 | -------------------------------------------------------------------------------- /src/test/pacode/510_invalidret1_err.pa: -------------------------------------------------------------------------------- 1 | func invalidret() -> int32, int64 2 | { 3 | return 1; 4 | } 5 | -------------------------------------------------------------------------------- /src/test/pacode/516_duplicate_const_err.pa: -------------------------------------------------------------------------------- 1 | const N = 10; 2 | int32 n = N; 3 | 4 | const N = 20; 5 | -------------------------------------------------------------------------------- /src/test/pacode/549_constarr_mv_err.pa: -------------------------------------------------------------------------------- 1 | func mvfun([3]int64 >>arr) 2 | { 3 | } 4 | 5 | mvfun([1,2,3]>>); 6 | -------------------------------------------------------------------------------- /src/test/pacode/555_arrlit_type_err7.pa: -------------------------------------------------------------------------------- 1 | test([1,[1,2],3]); 2 | 3 | func test([3]int64 arr) 4 | { 5 | } 6 | -------------------------------------------------------------------------------- /src/test/pacode/599_anysize_arr_err.pa: -------------------------------------------------------------------------------- 1 | [10,5]int32 a; 2 | @[?,5]int32 ra = a; 3 | @[10,?]int32 ra2 = a; 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libs/json"] 2 | path = libs/json 3 | url = https://github.com/nlohmann/json.git 4 | -------------------------------------------------------------------------------- /src/test/pacode/506_assigntype_err.pa: -------------------------------------------------------------------------------- 1 | int32 i32 = 10; 2 | [10]int32 ai; 3 | 4 | ai -> i32; 5 | 6 | exit(0); 7 | -------------------------------------------------------------------------------- /src/test/pacode/511_invalidret2_err.pa: -------------------------------------------------------------------------------- 1 | func invalidret() -> int32 int64 2 | { 3 | return 1, 2, 3; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /src/test/pacode/531_func_retval_err.pa: -------------------------------------------------------------------------------- 1 | 2 | 3 | func ret_err_func(int32 a) 4 | -> int32 b, int16 b { 3->b } 5 | -------------------------------------------------------------------------------- /src/test/pacode/533_func_retval_err3.pa: -------------------------------------------------------------------------------- 1 | 2 | func err_func(int64 a, int32 b) 3 | -> int64 a, b 4 | { 5 | } 6 | -------------------------------------------------------------------------------- /src/test/pacode/570_continue_notinloop_err.pa: -------------------------------------------------------------------------------- 1 | { 2 | int32 a; 3 | while a<10 { a+1->a } 4 | continue; 5 | } 6 | -------------------------------------------------------------------------------- /src/test/pacode/583_structtype_err2.pa: -------------------------------------------------------------------------------- 1 | type AB { 2 | int32 a; 3 | int64 b; 4 | }; 5 | 6 | AB ab = [1,2,3]; 7 | -------------------------------------------------------------------------------- /src/test/pacode/589_structinit_err.pa: -------------------------------------------------------------------------------- 1 | type A { 2 | int32 a; 3 | int16 b; 4 | }; 5 | 6 | @A x = [1, 2.2]; 7 | -------------------------------------------------------------------------------- /src/test/pacode/596_incompatiref_err2.pa: -------------------------------------------------------------------------------- 1 | int16 i16 = 16; 2 | @int16 i16x = i16; 3 | @int64 i64x = i16x; 4 | 5 | -------------------------------------------------------------------------------- /src/test/pacode/508_needretarg_err.pa: -------------------------------------------------------------------------------- 1 | func noretname(int32 a) -> int32 2 | { 3 | 3->a; 4 | return; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/test/pacode/560_arrval_type_err3.pa: -------------------------------------------------------------------------------- 1 | int64 i = 102; 2 | [2,3]int64 a 3 | = [1,i,3] 4 | [1,i]; 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/test/pacode/566_copyfreevar_err4.pa: -------------------------------------------------------------------------------- 1 | arr1 = [1,2,3]; 2 | arr2 <<= arr1; 3 | i = 3; 4 | [i,4,5] -> arr1; 5 | 6 | -------------------------------------------------------------------------------- /src/test/pacode/576_nomember_err.pa: -------------------------------------------------------------------------------- 1 | type nomem { 2 | int64 a; 3 | int64 b; 4 | }; 5 | 6 | nomem s; 7 | 10->s.x; 8 | -------------------------------------------------------------------------------- /src/test/pacode/578_structtype_err.pa: -------------------------------------------------------------------------------- 1 | type A { 2 | int32 a; 3 | }; 4 | 5 | A a; 6 | 7 | 3 -> a; 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/test/pacode/512_invalidret3_err.pa: -------------------------------------------------------------------------------- 1 | func invalidret() -> int32 int64 2 | { 3 | [10]int32 a; 4 | return a, 3; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/test/pacode/521_asgn_novalue_err.pa: -------------------------------------------------------------------------------- 1 | int16 a, b; 2 | 3 | no_ret(3) -> a, b; 4 | 5 | func no_ret(int16 x) 6 | { 7 | } 8 | -------------------------------------------------------------------------------- /src/test/pacode/564_arrval_type_err7.pa: -------------------------------------------------------------------------------- 1 | i = 12; 2 | test([i,[1,2],3]); 3 | 4 | func test([3]int64 arr) 5 | { 6 | } 7 | 8 | -------------------------------------------------------------------------------- /src/test/pacode/591_externdup_err2.pa: -------------------------------------------------------------------------------- 1 | extern int64 x; 2 | 3 | { 4 | extern int64 x; // OK 5 | extern int64 x; // NG 6 | } 7 | -------------------------------------------------------------------------------- /src/test/pacode/608_fixedarray_typecmp_err9.pa: -------------------------------------------------------------------------------- 1 | 2 | func readonly(@[10,2]int32 a) { 3 | } 4 | 5 | readonly("test"); 6 | 7 | -------------------------------------------------------------------------------- /src/test/pacode/515_undefchainfunc_err.pa: -------------------------------------------------------------------------------- 1 | int32 a, b; 2 | 3 | a, b -> test(3) -> b; 4 | 5 | func test(int32 a) -> int32 b 6 | { 7 | } 8 | -------------------------------------------------------------------------------- /src/test/pacode/568_voiditem_err.pa: -------------------------------------------------------------------------------- 1 | i=2; 2 | arr = [dd(1,2), 2, i+3]; 3 | 4 | func dd(int64 a, b) 5 | { 6 | printf("%d\n", a+b); 7 | } 8 | -------------------------------------------------------------------------------- /src/test/pacode/607_fixedarray_typecmp_err8.pa: -------------------------------------------------------------------------------- 1 | func readonly(@[10,2]int32 a) { 2 | } 3 | 4 | [10,3]int32 m; 5 | 6 | readonly(m); 7 | 8 | -------------------------------------------------------------------------------- /src/test/pacode/601_fixedarray_typecmp_err2.pa: -------------------------------------------------------------------------------- 1 | @[10]byte b = "abc"; // readonly 2 | 3 | movable(b); 4 | func movable([10]byte >>b) { 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/test/pacode/603_fixedarray_typecmp_err4.pa: -------------------------------------------------------------------------------- 1 | func readonlyanysize(@[?,2]int32 b) { 2 | } 3 | 4 | [10,3]int32 m; 5 | 6 | readonlyanysize(m); 7 | -------------------------------------------------------------------------------- /src/test/pacode/548_constarr_exp_err2.pa: -------------------------------------------------------------------------------- 1 | { 2 | const arr = [1,2,3][4,5,ifunc()]; 3 | } 4 | 5 | func ifunc() -> int32 6 | { 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /src/test/pacode/552_ambigfunc_err2.pa: -------------------------------------------------------------------------------- 1 | 2 | 3 | func afunc() 4 | { 5 | } 6 | 7 | func afunc(int64 a=10) 8 | { 9 | } 10 | 11 | afunc(); 12 | -------------------------------------------------------------------------------- /src/test/pacode/602_fixedarray_typecmp_err3.pa: -------------------------------------------------------------------------------- 1 | @[10]byte b = "abc"; // readonly 2 | 3 | movable(b>>); 4 | func movable([10]byte >>b) { 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/test/pacode/604_fixedarray_typecmp_err5.pa: -------------------------------------------------------------------------------- 1 | func readonlyanysize(@[?,2]int32 b) { 2 | } 3 | 4 | [10,2,3]int32 m; 5 | 6 | readonlyanysize(m); 7 | -------------------------------------------------------------------------------- /src/test/pacode/509_needret_err.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | func nonameret_func([10]int32 >> pa) -> int32 4 | { 5 | printf("no retrun"); 6 | } 7 | 8 | -------------------------------------------------------------------------------- /src/test/pacode/519_duplicate_func_err.pa: -------------------------------------------------------------------------------- 1 | test(4); 2 | 3 | func test(int32 a) 4 | { 5 | } 6 | 7 | func test(int32 b) -> int32 b 8 | { 9 | } 10 | -------------------------------------------------------------------------------- /src/test/pacode/543_copyfreevar_err2.pa: -------------------------------------------------------------------------------- 1 | // testing freeed var check in block 2 | 3 | [3]int64 arr; 4 | { 5 | arr1 <<= arr; 6 | [1,2,3] -> arr; 7 | } 8 | -------------------------------------------------------------------------------- /src/test/pacode/600_fixedarray_typecmp_err1.pa: -------------------------------------------------------------------------------- 1 | 2 | func writable(@![10]byte b) { 3 | } 4 | 5 | @[10]byte b = "abc"; // readonly 6 | 7 | writable(b); 8 | -------------------------------------------------------------------------------- /src/test/pacode/514_cantusemove_err.pa: -------------------------------------------------------------------------------- 1 | ccall exit(); 2 | 3 | [3]int32 arr, arr2; 4 | [2][3]int32 aa, bb; 5 | 6 | bb[0], arr[0] ->> aa[1], >>arr2[1]; 7 | exit(0); 8 | -------------------------------------------------------------------------------- /src/test/pacode/581_duptype_err.pa: -------------------------------------------------------------------------------- 1 | type A { 2 | int64 a; 3 | }; 4 | 5 | type B { 6 | int64 b; 7 | }; 8 | 9 | 10 | type A { 11 | flo64 a; 12 | }; 13 | -------------------------------------------------------------------------------- /src/test/pacode/605_fixedarray_typecmp_err6.pa: -------------------------------------------------------------------------------- 1 | func readonly(@[10,2]int32 a) { 2 | } 3 | 4 | [10,2,3]int32 m; 5 | @[?,2,3]int32 mm = m; 6 | 7 | readonly(mm); 8 | 9 | -------------------------------------------------------------------------------- /src/test/pacode/606_fixedarray_typecmp_err7.pa: -------------------------------------------------------------------------------- 1 | func readonly(@[10,2]int32 a) { 2 | } 3 | 4 | [10,3]int32 m; 5 | @[?,3]int32 mm = m; 6 | 7 | readonly(mm); 8 | 9 | -------------------------------------------------------------------------------- /src/test/pacode/001_helloworld.pa: -------------------------------------------------------------------------------- 1 | syscall 1: write(...) -> int64; 2 | ccall printf(...); 3 | 4 | int64 n = write(1, "Hello World!\n", 13); 5 | printf("%d", n); 6 | 7 | -------------------------------------------------------------------------------- /idea/Import.pa: -------------------------------------------------------------------------------- 1 | import "test" // import names to current namespace. 2 | import "../test2" as t2 // expand as t2 namespace 3 | 4 | test_func(); 5 | t2.test_func(); 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/test/pacode/544_copyfreevar_err3.pa: -------------------------------------------------------------------------------- 1 | [3]int64 arr1 = [1,2,3]; 2 | { 3 | freearr(arr1>>) -> arr1; 4 | } 5 | 6 | func freearr([3]int64 >>arr) -> [3]int64 arr 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /src/test/pacode/574_cantusemove_err3.pa: -------------------------------------------------------------------------------- 1 | [10]int32 a; 2 | 3 | reffunc(a); 4 | 5 | func reffunc(@[10]int32 aa) 6 | { 7 | [10]int32 bb; 8 | 9 | bb ->> aa; 10 | } 11 | -------------------------------------------------------------------------------- /src/test/pacode/575_copy2rovar_err.pa: -------------------------------------------------------------------------------- 1 | [10]int32 a; 2 | 3 | reffunc(a); 4 | 5 | func reffunc(@[10]int32 aa) 6 | { 7 | [10]int32 bb; 8 | 9 | bb -> aa; 10 | } 11 | -------------------------------------------------------------------------------- /src/test/pacode/505_ambigfunc_err.pa: -------------------------------------------------------------------------------- 1 | int32 i32 = 10; 2 | 3 | ambi_func(i32); 4 | 5 | func ambi_func(int64 i) 6 | { 7 | } 8 | 9 | func ambi_func(int16 i) 10 | { 11 | } 12 | -------------------------------------------------------------------------------- /src/test/pacode/590_externdup_err.pa: -------------------------------------------------------------------------------- 1 | extern flo64 x; 2 | 3 | { 4 | extern flo64 x; // OK; 5 | } 6 | { 7 | int64 x = 10; // OK; hiding global x. 8 | } 9 | 10 | { 11 | x = 10; // NG; override global x. foolproof. 12 | } 13 | -------------------------------------------------------------------------------- /src/test/pacode/036_methodcall.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | type A { 3 | int64 a; 4 | int64 b; 5 | }; 6 | 7 | $A a = [1, 2]; 8 | 9 | func f(@A a) { 10 | printf("x"); 11 | } 12 | 13 | func f(@!A a) { 14 | printf("%d", a.b); 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.log 3 | *.tab.* 4 | *.gcov 5 | core.* 6 | core 7 | .exrc 8 | PlnLexer.cpp 9 | PlnParser.cpp 10 | PlnParser.hpp 11 | location.hh 12 | position.hh 13 | stack.hh 14 | pac 15 | pat 16 | src/test/tester 17 | src/test/cuitester 18 | src/test/out 19 | -------------------------------------------------------------------------------- /src/test/pacode/573_cantusemove_err2.pa: -------------------------------------------------------------------------------- 1 | [10]int32 a; 2 | 3 | reffunc(a); 4 | 5 | func reffunc(@[10]int32 aa) 6 | { 7 | mvfunc(aa>>); // Error at here currently. 8 | } 9 | 10 | func mvfunc(@[10]int32 >>aa) // However, this gammer should be NG. 11 | { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/test/testBase.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "catch.hpp" 3 | 4 | using namespace std; 5 | 6 | int clean(); 7 | int clean_ui(); 8 | string build(const string &srcf); 9 | string exec(string srcf); 10 | string mcheck(const string &tracef); 11 | 12 | extern bool disableOptimize; 13 | -------------------------------------------------------------------------------- /idea/Class.hpa: -------------------------------------------------------------------------------- 1 | // hash: dfadfasdfadfadsfadf 2 | // auto careated 3 | 4 | class foo { 5 | data: 6 | reserved: 2; 7 | io int a; 8 | out string s; 9 | reserved: 1; 10 | method: 11 | 12 | /// foo constractor 13 | /// 14 | /// @param aa aa value. 15 | construct(int aa = 0); 16 | 17 | virtual int ff(); 18 | } 19 | -------------------------------------------------------------------------------- /src/generators/PlnX86_64RegisterSave.h: -------------------------------------------------------------------------------- 1 | /// x86-64 (Linux) register save algorithm functions 2 | /// 3 | /// @file PlnX86_64RegisterSave.h 4 | /// @copyright 2020 YAMAGUCHI Toshinobu 5 | 6 | void addRegSave(vector &opecodes, int &cur_stacksize); 7 | void addRegSaveWithCFAnalysis(vector &opecodes, int &cur_stacksize); 8 | -------------------------------------------------------------------------------- /src/test/cuiTestBase.h: -------------------------------------------------------------------------------- 1 | 2 | using namespace std; 3 | 4 | int clean(); 5 | string build(const string &srcf); 6 | string outstr(const string &srcf); 7 | string errstr(const string &srcf); 8 | string outfile(string outf); 9 | string exec_pac(string srcf, const string &preopt, string outf, const string &postopt, const string &srcdir="pacode/"); 10 | -------------------------------------------------------------------------------- /src/test/pacode/003_varbyte.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | byte a = 12; 4 | byte b = a+7; 5 | byte c,d = b+1+a, b-a; 6 | { 7 | byte tmp = d+1; // tmp memory should be share with e. 8 | } 9 | byte e = 0xff; 10 | int64 i = e+a; 11 | byte i2 = 3*a; 12 | byte i3 = a*b; 13 | 14 | printf("%d %d %d %d %d %d %d\n", b, c, d, e, i, i2, i3); 15 | 16 | -------------------------------------------------------------------------------- /src/test/cuiTestMain.cpp: -------------------------------------------------------------------------------- 1 | #define CATCH_CONFIG_RUNNER 2 | #include 3 | #include "catch.hpp" 4 | #include "cuiTestBase.h" 5 | 6 | int main(int argc, char* argv[]) 7 | { 8 | if (clean()) 9 | fprintf(stderr, "Cleaning output dir is faild."); 10 | int result = Catch::Session().run(argc, argv); 11 | 12 | return (result < 0xff ? result : 0xff); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/test/testMain.cpp: -------------------------------------------------------------------------------- 1 | #define CATCH_CONFIG_RUNNER 2 | #include "catch.hpp" 3 | #include 4 | 5 | #include "testBase.h" 6 | 7 | int main(int argc, char* argv[]) 8 | { 9 | if (clean()) 10 | fprintf(stderr, "Cleaning output dir is faild."); 11 | int result = Catch::Session().run(argc, argv); 12 | 13 | return (result < 0xff ? result : 0xff); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/PlnModelTreeBuilder.h: -------------------------------------------------------------------------------- 1 | /// Build model trees from AST json declaration. 2 | /// 3 | /// @file PlnModelTreeBuilder.h 4 | /// @copyright 2018 YAMAGUCHI Toshinobu 5 | 6 | #include "../libs/json/single_include/nlohmann/json.hpp" 7 | using json = nlohmann::json; 8 | 9 | class PlnModule; 10 | class PlnModelTreeBuilder 11 | { 12 | public: 13 | PlnModelTreeBuilder(); 14 | PlnModule* buildModule(json& ast); 15 | }; 16 | -------------------------------------------------------------------------------- /src/PlnException.h: -------------------------------------------------------------------------------- 1 | /// Exception difinition 2 | /// 3 | /// @file PlnException.h 4 | /// @copyright 2018 YAMAGUCHI Toshinobu 5 | 6 | class PlnCompileError : public std::exception { 7 | public: 8 | PlnErrCode err_code; 9 | string arg1, arg2; 10 | PlnLoc loc; 11 | 12 | PlnCompileError(PlnErrCode err_code, string arg1="\x01", string arg2="\x01") 13 | : err_code(err_code), arg1(arg1), arg2(arg2) 14 | {} 15 | }; 16 | 17 | -------------------------------------------------------------------------------- /src/test/pacode/577_cantusemove_err4.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | ccall time(uint64 tloc)->uint64; 3 | ccall localtime(@uint64 t) -> @struct_tm; 4 | 5 | type struct_tm { 6 | int32 tm_sec; 7 | int32 tm_min; 8 | int32 tm_hour; 9 | int32 tm_mday; 10 | int32 tm_mon; 11 | int32 tm_year; 12 | int32 tm_wday; 13 | int32 tm_yday; 14 | int32 tm_isdst; 15 | }; 16 | 17 | t = time(0); 18 | struct_tm stm <<= 19 | localtime(t); 20 | 21 | -------------------------------------------------------------------------------- /src/test/pacode/000_temp.pa: -------------------------------------------------------------------------------- 1 | ccall printf(@[?]byte format, ...) -> int32; 2 | 3 | // [3][4]int32 a1; 4 | // [5][6]int32 a2; 5 | // // set_arrarr(a1>>) ->> a1; 6 | // //inc_arrarr(a1); 7 | // 11 -> a1[2][3]; 8 | // printf("%d", a1[2][3]); 9 | // 10 | // [3]#[10]byte names = ["Alice","Bob","Ken"]; 11 | // 12 | // [1,10]int32 xx; 13 | [2]int32 a2; 14 | [3]int32 a3; 15 | 16 | // a2 ->> a3; 17 | 18 | @[2]int32 x = a2; 19 | // object x2 = a2; 20 | -------------------------------------------------------------------------------- /src/ast/PlnLexer.h: -------------------------------------------------------------------------------- 1 | /// Palan Lexer class declaration. 2 | /// 3 | /// @file PlnLexer.h 4 | /// @copyright 2017-2019 YAMAGUCHI Toshinobu 5 | 6 | #ifndef FLEX_SCANNER 7 | #include 8 | #endif 9 | 10 | class PlnLexer : public yyFlexLexer { 11 | public: 12 | vector filenames; 13 | int cur_fid; 14 | 15 | void set_filename(const std::string& filename); 16 | int yylex(palan::PlnParser::semantic_type& lval, palan::PlnParser::location_type& loc); 17 | }; 18 | -------------------------------------------------------------------------------- /tools/loc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | find src -type d -name test -prune \ 4 | -o -type d -name ast -prune \ 5 | -o -type f -name '*.cpp' -print \ 6 | -o -type f -name '*.h' -print \ 7 | | xargs wc -l 8 | 9 | echo "" 10 | 11 | find src/ast \ 12 | -type f -name '*.cpp' \ 13 | -not -name 'PlnParser.cpp' -not -name 'PlnLexer.cpp' -print \ 14 | -o -type f -name '*.h' -print \ 15 | -o -type f -name '*.yy' -print \ 16 | -o -type f -name '*.ll' -print \ 17 | | xargs wc -l 18 | 19 | -------------------------------------------------------------------------------- /src/test/pacode/014_const.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | const N,M = 3, 9+2; 4 | const NN = N+3; 5 | printf(TEST_STR, M); 6 | 7 | [NN]byte a; 8 | f(a); 9 | 10 | func f([N*2]byte n) 11 | { 12 | [5]byte arr; 13 | printf(TEST_STR, N); 14 | arr -> f(); 15 | 16 | func f([N]byte n) { 17 | printf(TEST_STR, N); 18 | const TEST_STR = "test3 %d\n"; 19 | } 20 | const N = 5; 21 | const TEST_STR = "test2 %d\n"; 22 | } 23 | 24 | printf(TEST_STR, N); 25 | 26 | const TEST_STR = "test1 %d\n"; 27 | 28 | -------------------------------------------------------------------------------- /src/generators/PlnX86_64CalcOptimization.h: -------------------------------------------------------------------------------- 1 | /// x86-64 (Linux) calculation optimization declarations. 2 | /// 3 | /// @file PlnX86_64CalcOptimization.h 4 | /// @copyright 2021 YAMAGUCHI Toshinobu 5 | 6 | bool tryOptiMul(PlnX86_64RegisterMachine &m, PlnGenEntity* tgt, PlnGenEntity* scnd, string& comment); 7 | bool tryOptiDiv(PlnX86_64RegisterMachine &m, PlnGenEntity* tgt, PlnGenEntity* scnd, string& comment); 8 | bool tryOptiMod(PlnX86_64RegisterMachine &m, PlnGenEntity* tgt, PlnGenEntity* scnd, string& comment); 9 | -------------------------------------------------------------------------------- /idea/Helloworld.pa: -------------------------------------------------------------------------------- 1 | // point1: ":"で区切って横に書くと並列処理される。(どちらが先に処理されるか不定) 2 | // ;で 待ち合わせを行う。 3 | print("Hello World!\n"): print("Hello Palan!\n"); 4 | 5 | // Point: ":"の最初が配列の場合、要素分の処理が走る。 6 | [1..5]:print("Hello Palan World" _.str "!\n"); 7 | 8 | // Point: ":"の最初が整数場合、その分の処理が走る。 9 | 2:workerTask(0); 10 | 11 | // worker 処理 非同期処理の場合(先頭に^) 12 | []int32 n = [0,0]; 13 | ^n.size: workerTask(n[_]) -> n[_]; 14 | 15 | wait until(n.total()==2) { 16 | } timeout(1000) { 17 | } 18 | 19 | func workerTask(int32 n) -> n 20 | { 21 | sleep(1000); 22 | ++n; 23 | } 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Additional context** 24 | Add any other context about the problem here. 25 | -------------------------------------------------------------------------------- /src/models/expressions/PlnReferenceValue.h: -------------------------------------------------------------------------------- 1 | /// PlnReferenceValue model class declaration. 2 | /// 3 | /// @file PlnReferenceValue.h 4 | /// @copyright 2020 YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnExpression.h" 7 | 8 | class PlnReferenceValue : public PlnExpression 9 | { 10 | public: 11 | PlnExpression* refvar_ex; 12 | PlnReferenceValue(PlnExpression *refvar_ex); 13 | ~PlnReferenceValue(); 14 | 15 | PlnExpression* adjustTypes(const vector &types) override; 16 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 17 | void gen(PlnGenerator& g) override; 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /src/test/pacode/102_lsm.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | const N = 5; 4 | var x, y = 5 | [1.1, 2.3, 2.8, 4.2, 5.1], 6 | [0.7, 1.9, 3.1, 4.2, 5.6]; 7 | 8 | printf("%.3f, %.3f\n", lsm(x, y)); 9 | 10 | func lsm([N]flo64 x, y) -> flo64 a0, a1 11 | { 12 | flo64 a00, a01, a02, a11, a12 = 0,0,0,0,0; 13 | 14 | i=0; 15 | while i a00; 17 | a01 + x[i] -> a01; 18 | a02 + y[i] -> a02; 19 | a11 + x[i]*x[i] -> a11; 20 | a12 + x[i]*y[i] -> a12; 21 | i++; 22 | } 23 | 24 | (a02*a11-a01*a12) / (a00*a11-a01*a01) -> a0; 25 | (a00*a12-a01*a02) / (a00*a11-a01*a01) -> a1; 26 | } 27 | -------------------------------------------------------------------------------- /src/test/pacode/012_overload.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | uint16 i16 = 16; 4 | int32 i32 = 32; 5 | [10]int32 ia; 6 | 7 | ov_func(ia>>); 8 | ov_func(i16); 9 | ov_func(i32); 10 | ov_func(i32, i16); 11 | ov_func(ret2u()); 12 | 13 | func ov_func([10]int32 >> pa) 14 | { 15 | printf("(int32[10])"); 16 | } 17 | 18 | func ov_func(int32 pa) 19 | { 20 | printf("(int32)"); 21 | } 22 | 23 | func ov_func(uint16 pa) 24 | { 25 | printf("(uint16)"); 26 | } 27 | 28 | func ov_func(uint32 pa, uint32 pb) 29 | { 30 | printf("(uint32 %d, uint32 %d)", pa, pb); 31 | } 32 | 33 | func ret2u() -> uint64, uint64 34 | { 35 | return 1u,2u; 36 | } 37 | -------------------------------------------------------------------------------- /src/models/types/PlnArrayValueType.h: -------------------------------------------------------------------------------- 1 | /// Array value type class declaration. 2 | /// 3 | /// @file PlnArrayValueType.h 4 | /// @copyright 2019-2020 YAMAGUCHI Toshinobu 5 | 6 | class PlnArrayValue; 7 | class PlnArrayValueTypeInfo : public PlnTypeInfo { 8 | public: 9 | PlnArrayValue *arr_val; 10 | PlnArrayValueTypeInfo(PlnArrayValue* arr_val); 11 | PlnTypeConvCap canCopyFrom(const string &mode, PlnVarType *src, PlnAsgnType copymode) override; 12 | 13 | PlnVarType* getDefaultType(PlnBlock *block); 14 | vector getArraySizes(); 15 | 16 | PlnTypeConvCap checkCompatible(PlnVarType* item_type, const vector& sizes); 17 | }; 18 | -------------------------------------------------------------------------------- /src/test/pacode/018_floarr.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | ccall setenv(...); 3 | ccall mtrace(); 4 | ccall muntrace(); 5 | 6 | setenv("MALLOC_TRACE", "out/mtrace018", 1); 7 | // alloc only 8 | [10]flo32 f; 9 | [3]flo64 d1, d2; 10 | int32 i,j = 1,2; 11 | 12 | mtrace(); 13 | arr_func(d1>>) ->> d1; 14 | muntrace(); 15 | printf("%.2f %.2f", d1[i], d1[j]); 16 | 17 | [5,3]flo32 ff; 18 | d1[i],d1[j] -> ff[i,j], ff[j,i]; 19 | printf(" %.2f %.2f", ff[i,j], ff[j,i]); 20 | 21 | func arr_func([3]flo64 >>da) -> [3]flo64 da 22 | { 23 | [5]flo32 a; 24 | 1.8 -> a[0]; 2.5 -> a[3.5]; 25 | 1.23 -> da[1]; 26 | 3, da[a[0]]*a[0] -> a[0], da[a[3]]; 27 | } 28 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | @mkdir -p bin 3 | @$(MAKE) -C src 4 | @cp src/pac bin/ 5 | @cp src/ast/pat bin/ 6 | clean: 7 | @rm -f bin/* 8 | @$(MAKE) -C src clean 9 | package: 10 | -apt-get -y install libboost-dev 11 | -apt-get -y install libboost-program-options-dev 12 | -apt-get -y install bison 13 | -apt-get -y install flex 14 | -apt-get -y install libfl-dev 15 | -curl -o src/test/catch.hpp https://raw.githubusercontent.com/catchorg/Catch2/v2.x/single_include/catch2/catch.hpp 16 | coverage: 17 | @$(MAKE) -C src coverage 18 | release: clean 19 | @mkdir -p bin 20 | @$(MAKE) -C src release 21 | @cp src/pac bin/ 22 | @cp src/ast/pat bin/ 23 | 24 | -------------------------------------------------------------------------------- /src/models/PlnModule.h: -------------------------------------------------------------------------------- 1 | /// Module model class declaration. 2 | /// 3 | /// @file PlnModule.h 4 | /// @copyright 2017-2020 YAMAGUCHI Toshinobu 5 | 6 | #include 7 | #include 8 | #include "PlnExpression.h" 9 | 10 | // Module: Type, ReadOnlyData, Functions 11 | class PlnCompileError; 12 | class PlnModule 13 | { 14 | public: 15 | PlnBlock* toplevel; 16 | int max_jmp_id; 17 | bool do_opti_regalloc = true; 18 | vector functions; 19 | 20 | PlnModule(); 21 | PlnModule(const PlnModule&) = delete; 22 | ~PlnModule(); 23 | 24 | int getJumpID(); 25 | 26 | void gen(PlnDataAllocator& da, PlnGenerator& g); 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /src/models/expressions/PlnMulOperation.h: -------------------------------------------------------------------------------- 1 | /// PlnMulOperation model class declaration. 2 | /// 3 | /// @file PlnMulOperation.h 4 | /// @copyright 2017-2019 YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnExpression.h" 7 | 8 | class PlnMulOperation : public PlnExpression 9 | { 10 | public: 11 | PlnExpression *l, *r; 12 | PlnDataPlace *ldp, *rdp; 13 | bool do_cross; 14 | 15 | PlnMulOperation(PlnExpression* l, PlnExpression* r); 16 | ~PlnMulOperation(); 17 | 18 | static PlnExpression* create(PlnExpression* l, PlnExpression* r); 19 | 20 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 21 | void gen(PlnGenerator& g) override; 22 | }; 23 | 24 | -------------------------------------------------------------------------------- /src/test/pacode/034_increment.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | i = 0; 4 | i++; 5 | 6 | printf("%d ", i); 7 | 8 | sbyte b = -5; 9 | b++; 10 | printf("%d ",b); 11 | 12 | [3]int16 ia = [11,22,33]; 13 | ia[ind(1)]++; 14 | printf("%d ", ia[1]); 15 | 16 | [2][3]int16 ia2 = [11,21,31][12,22,32]; 17 | ia2[1][ind(1)]++; 18 | printf("%d ", ia2[1][1]); 19 | 20 | Test t = [11, 22.2]; 21 | t.ii++; t.ff++; 22 | printf("%d %.1f\n", t.ii, t.ff); 23 | 24 | // decrement 25 | int16 ii = 10; 26 | ii--; 27 | printf("%d ", ii); 28 | 29 | func ind(int64 i) -> int64 30 | { 31 | printf("!"); 32 | return i; 33 | } 34 | 35 | type Test { 36 | int32 ii; 37 | flo32 ff; 38 | }; 39 | 40 | -------------------------------------------------------------------------------- /src/ast/PlnAstMessage.h: -------------------------------------------------------------------------------- 1 | /// Message definitions. 2 | /// 3 | /// Manage output message descriptions in Palan parser. 4 | /// 5 | /// @file PlnAstMessage.h 6 | /// @copyright 2021 YAMAGUCHI Toshinobu 7 | 8 | #include 9 | using std::string; 10 | 11 | #define PAT_ERR_MSG_START_NO 0 12 | enum PlnErrCode { 13 | E_CouldnotOpenFile = PAT_ERR_MSG_START_NO, // file name 14 | }; 15 | 16 | enum PlnHelpCode { 17 | H_Help, 18 | H_Output, 19 | H_Indent, 20 | H_Input 21 | }; 22 | 23 | class PlnAstMessage 24 | { 25 | public: 26 | static string getErr(PlnErrCode err_code, string arg1="\x01", string arg2="\x01"); 27 | static const char* getHelp(PlnHelpCode help_code); 28 | }; 29 | -------------------------------------------------------------------------------- /src/models/expressions/PlnStructMember.h: -------------------------------------------------------------------------------- 1 | /// PlnStructMember model class declaration. 2 | /// 3 | /// @file PlnStructMember.h 4 | /// @copyright 2019 YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnExpression.h" 7 | 8 | class PlnStructMemberDef; 9 | class PlnStructMember : public PlnExpression 10 | { 11 | public: 12 | PlnExpression* struct_ex; 13 | PlnStructMemberDef* def; 14 | 15 | PlnStructMember(PlnExpression* sturct_ex, string member_name); 16 | ~PlnStructMember(); 17 | 18 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 19 | void gen(PlnGenerator& g) override; 20 | 21 | static vector getAllStructMembers(PlnVariable* var); 22 | }; 23 | 24 | -------------------------------------------------------------------------------- /src/test/pacode/029_typealias.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...) -> int32; 2 | 3 | type A { 4 | int32 x; 5 | int32 y; 6 | }; 7 | 8 | type B = A; 9 | type Point = [2]flo32; 10 | type int = int32; 11 | 12 | int x = test(66); 13 | printf("%d ", x); 14 | 15 | { 16 | Point p = [33,44]; 17 | [3]Point p3 = [1,2][3,4][5,6]; 18 | 19 | printf("%.1f ", p3[1][1]); 20 | p -> p3[1]; 21 | printf("%.1f ", p3[1][1]); 22 | 23 | type C = B; 24 | A a; 25 | 11,22 -> a.x, a.y; 26 | B b = a; 27 | printf("%d %d ", b.x, b.y); 28 | C c; 29 | 33 -> a.x; 30 | a -> b -> c; 31 | printf("%d %d", c.x, c.y); 32 | } 33 | 34 | func test(int i) -> int i 35 | { 36 | printf("%d ", i); 37 | 99 -> i; 38 | } 39 | -------------------------------------------------------------------------------- /src/test/pacode/022_type_inference.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | i = 9; 4 | u = 10u; 5 | f = 12.3; 6 | printf("%d%u%.1f ", i, u, f); 7 | 8 | j = i; 9 | v = u; 10 | d = f; 11 | printf("%d%u%.1f ", j, v, d); 12 | 13 | var a, b, c = i, u, f; 14 | printf("%d%d%d ", a, b, c); 15 | 16 | var a2, var b2, var c2 = i, u, f; 17 | printf("%d%u%.1f\n", a2, b2, c2); 18 | 19 | arr1 = [1,2,3]; 20 | arr2 = [1.1, 1.2, 1.3][2.1, 2.2, 2.3]; 21 | 22 | printf("%d%.1f ", arr1[2], arr2[1,1]); 23 | 24 | [3]int64 arr11 = arr1; 25 | [2,3]flo64 arr21 = arr2; 26 | 27 | [4][2,3]int16 arr3; 28 | [1,2,3][4,5,6] -> arr3[2]; 29 | 30 | arr31 = arr3; 31 | 32 | printf("%d ", arr31[2][1,1]); 33 | 34 | str = "abc"; 35 | printf("%s", str); 36 | -------------------------------------------------------------------------------- /src/models/expressions/PlnAssignment.h: -------------------------------------------------------------------------------- 1 | /// PlnAssignment model class declaration. 2 | /// 3 | /// @file PlnAssignment.h 4 | /// @copyright 2017-2020 YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnExpression.h" 7 | 8 | class PlnAssignItem; 9 | 10 | // Assignment: lvals Expression 11 | class PlnAssignment : public PlnExpression 12 | { 13 | public: 14 | PlnAssignment(vector& dst_vals, vector& exps); // throw PlnCompileError 15 | ~PlnAssignment(); 16 | vector lvals; 17 | vector expressions; 18 | vector assgin_items; 19 | 20 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 21 | void gen(PlnGenerator& g) override; 22 | }; 23 | 24 | -------------------------------------------------------------------------------- /src/test/pacode/032_ptrptr.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | ccall topen(@[?]byte name => TestDb tdb>>) -> int32 : "capi4test.o"; 4 | ccall topen2(@[?]byte name => int32 stat, TestDb tdb>>) -> int32; 5 | ccall tgetId(@TestDb tdb) -> int32; 6 | ccall tgetName(@TestDb tdb) -> @[?]byte; 7 | ccall tclose(TestDb >>tdb); 8 | ccall tprintparray([2][3]int64 parray, int64 num1, num2); 9 | 10 | type TestDb; 11 | 12 | TestDb tdb, tdb2; 13 | int32 stat; 14 | topen("test" =>> tdb); 15 | topen2("test2" => stat, >>tdb2); 16 | 17 | printf("%s %d %s ", tgetName(tdb), tgetId(tdb), tgetName(tdb2)); 18 | 19 | tclose(tdb>>); 20 | tclose(tdb2>>); 21 | { 22 | [2][3]int64 parray = [1,2,3][4,5,6]; 23 | tprintparray(parray, 2, 3); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/test/depend.inc: -------------------------------------------------------------------------------- 1 | testMain.o: catch.hpp testBase.h 2 | testBase.o: testBase.h catch.hpp \ 3 | ../generators/PlnX86_64DataAllocator.h \ 4 | ../generators/../PlnDataAllocator.h ../generators/PlnX86_64Generator.h \ 5 | ../generators/../PlnGenerator.h ../generators/PlnX86_64RegisterMachine.h \ 6 | ../models/PlnModule.h ../models/PlnExpression.h ../models/../PlnModel.h \ 7 | ../PlnModelTreeBuilder.h \ 8 | ../../libs/json/single_include/nlohmann/json.hpp ../PlnMessage.h \ 9 | ../PlnException.h 10 | basicTest.o: testBase.h catch.hpp 11 | dataAllocTest.o: testBase.h catch.hpp \ 12 | ../generators/PlnX86_64DataAllocator.h \ 13 | ../generators/../PlnDataAllocator.h ../PlnConstants.h 14 | algorithmTest.o: testBase.h catch.hpp 15 | -------------------------------------------------------------------------------- /src/models/expressions/PlnCmpOperation.h: -------------------------------------------------------------------------------- 1 | /// PlnCmpOperation model class declaration. 2 | /// 3 | /// @file PlnCmpOperation.h 4 | /// @copyright 2018-2020 YAMAGUCHI Toshinobu 5 | 6 | #include "PlnBoolExpression.h" 7 | 8 | class PlnCmpOperation : public PlnBoolExpression 9 | { 10 | public: 11 | PlnCmpType cmp_type; 12 | 13 | PlnDataPlace* result_dp; 14 | PlnExpression* l; 15 | PlnExpression* r; 16 | 17 | PlnCmpOperation(PlnExpression* l, PlnExpression* r, PlnCmpType cmp_type); 18 | ~PlnCmpOperation(); 19 | 20 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 21 | void gen(PlnGenerator& g) override; 22 | 23 | static PlnExpression* create(PlnExpression* l, PlnExpression* r, PlnCmpType cmp_type); 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /src/test/algorithmTest.cpp: -------------------------------------------------------------------------------- 1 | #include "testBase.h" 2 | 3 | static void algorithmTest() 4 | { 5 | string testcode; 6 | 7 | testcode = "100_qsort"; 8 | REQUIRE(build(testcode) == "success"); 9 | REQUIRE(exec(testcode) == "before: 0 4 8 3 7 2 6 1 5 0\n" 10 | "after: 0 0 1 2 3 4 5 6 7 8"); 11 | testcode = "101_8queen"; 12 | REQUIRE(build(testcode) == "success"); 13 | REQUIRE(exec(testcode) == "answer: 92"); 14 | 15 | testcode = "102_lsm"; 16 | REQUIRE(build(testcode) == "success"); 17 | REQUIRE(exec(testcode) == "-0.633, 1.204"); 18 | } 19 | 20 | TEST_CASE("basic algorithm code example.", "[algorithm]") 21 | { 22 | disableOptimize = true; 23 | algorithmTest(); 24 | disableOptimize = false; 25 | algorithmTest(); 26 | } 27 | -------------------------------------------------------------------------------- /src/models/PlnConditionalBranch.h: -------------------------------------------------------------------------------- 1 | /// Conditi Branch model classes declaration. 2 | /// 3 | /// @file PlnConditionalBranch.h 4 | /// @copyright 2018-2020 YAMAGUCHI Toshinobu 5 | 6 | #include "PlnStatement.h" 7 | 8 | class PlnBoolExpression; 9 | class PlnIfStatement : public PlnStatement 10 | { 11 | public: 12 | PlnBoolExpression* condition; 13 | int jmp_next_id, jmp_end_id; 14 | PlnDataPlace* cond_dp; 15 | PlnStatement* next; 16 | 17 | PlnIfStatement(PlnExpression* condition, PlnBlock* block, PlnStatement* next, PlnBlock* parent); 18 | PlnIfStatement(const PlnIfStatement &) = delete; 19 | ~PlnIfStatement(); 20 | 21 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 22 | void gen(PlnGenerator& g) override; 23 | }; 24 | 25 | -------------------------------------------------------------------------------- /src/generators/PlnX86_64RegisterMachineImp.h: -------------------------------------------------------------------------------- 1 | /// x86-64 (Linux) register machine inner class declaration. 2 | /// 3 | /// @file PlnX86_64RegisterMachineImp.h 4 | /// @copyright 2019-2020 YAMAGUCHI Toshinobu 5 | 6 | class PlnOpeCode { 7 | public: 8 | PlnX86_64Mnemonic mne; 9 | PlnOperandInfo *src, *dst; 10 | string comment; 11 | int mark; 12 | PlnOpeCode(PlnX86_64Mnemonic mne, PlnOperandInfo *src, PlnOperandInfo* dst, string comment) 13 | : mne(mne), src(src), dst(dst), comment(comment), mark(0) {} 14 | }; 15 | 16 | class PlnX86_64RegisterMachineImp 17 | { 18 | public: 19 | bool has_call = false; 20 | int ret_num = 0; 21 | int requested_stack_size = 0; 22 | vector opecodes; 23 | PlnX86_64RegisterMachineImp() { 24 | }; 25 | }; 26 | -------------------------------------------------------------------------------- /src/test/pacode/038_calcopti.pa: -------------------------------------------------------------------------------- 1 | ccall printf(@[?]byte format, ...) -> int32; 2 | 3 | int64 a, b = div4(30); 4 | printf("%d %d", a, b); 5 | 6 | uint64 aa, bb = udiv4(30); 7 | printf(" %d %d", aa, bb); 8 | 9 | div2(-31) -> a, b; 10 | printf(" %d %d", a, b); 11 | 12 | div4(-30) -> a, b; 13 | printf(" %d %d", a, b); 14 | 15 | div8(-67) -> a, b; 16 | printf(" %d %d", a, b); 17 | 18 | func div2(int64 n) -> int64 a, b 19 | { 20 | n / 2 -> a; 21 | n % 2 -> b; 22 | } 23 | 24 | func div4(int64 n) -> int64 a, b 25 | { 26 | n / 4 -> a; 27 | n % 4 -> b; 28 | } 29 | 30 | func div8(int64 n) -> int64 a, b 31 | { 32 | n / 8 -> a; 33 | n % 8 -> b; 34 | } 35 | 36 | func udiv4(uint64 n) -> uint64 a, b 37 | { 38 | n / 4u -> a; 39 | n % 4u -> b; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/PlnTreeBuildHelper.h: -------------------------------------------------------------------------------- 1 | /// Helper functions for building model tree directly. 2 | /// 3 | /// @file PlnBuildTreeHelper.h 4 | /// @copyright 2018-2022 YAMAGUCHI Toshinobu 5 | 6 | #include "PlnModel.h" 7 | 8 | namespace palan 9 | { 10 | PlnVariable* declareUInt(PlnBlock* block, string name, uint64_t init_i); 11 | void incrementUInt(PlnBlock* block, PlnVariable *var, uint64_t inc); 12 | 13 | void malloc(PlnBlock* block, PlnVariable* var, PlnExpression* alloc_size_ex); 14 | void free(PlnBlock* block, PlnVariable* var); 15 | void exit(PlnBlock* block, uint64_t result); 16 | 17 | PlnArrayItem* rawArrayItem(PlnVariable* var, PlnVariable* index); 18 | 19 | PlnBlock* whileLess(PlnBlock* block, PlnVariable *var, PlnExpression* loop_num_ex); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - name: prepare lcov 11 | run: sudo apt-get install lcov 12 | 13 | - uses: actions/checkout@v2 14 | with: 15 | submodules: true 16 | 17 | - name: make package 18 | run: sudo make package 19 | - name: make 20 | run: make coverage 21 | 22 | - name: lcov 23 | run: | 24 | lcov -c -d . -b src -o all.info 25 | lcov -e all.info */palan/src/* -o lcov.info 26 | 27 | - name: Coveralls 28 | uses: coverallsapp/github-action@master 29 | with: 30 | github-token: ${{ secrets.GITHUB_TOKEN }} 31 | path-to-lcov: ./lcov.info 32 | 33 | -------------------------------------------------------------------------------- /src/models/expressions/assignitem/PlnAssignItem.h: -------------------------------------------------------------------------------- 1 | /// Assignment Item class definition. 2 | /// 3 | /// Interface of assignment item classes. 4 | /// 5 | /// @file PlnAssignItem.h 6 | /// @copyright 2018 YAMAGUCHI Toshinobu 7 | 8 | // PlnAssignItem 9 | class PlnAssignItem { 10 | public: 11 | virtual void addDstEx(PlnExpression* ex, bool need_save) = 0; 12 | virtual int addDataPlace(vector &data_places, int start_ind) = 0; 13 | 14 | virtual void finishS(PlnDataAllocator& da, PlnScopeInfo& si) = 0; 15 | virtual void finishD(PlnDataAllocator& da, PlnScopeInfo& si) = 0; 16 | virtual void genS(PlnGenerator& g) = 0; 17 | virtual void genD(PlnGenerator& g) = 0; 18 | 19 | static PlnAssignItem* createAssignItem(PlnExpression* ex); 20 | virtual ~PlnAssignItem() {}; 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /src/models/types/PlnAliasType.h: -------------------------------------------------------------------------------- 1 | /// Alias type class declaration. 2 | /// 3 | /// @file PlnAliasType.h 4 | /// @copyright 2019-2022 YAMAGUCHI Toshinobu 5 | 6 | class PlnAliasTypeInfo : public PlnTypeInfo { 7 | public: 8 | PlnVarType* orig_type; 9 | PlnAliasTypeInfo(const string &name, PlnVarType* orig_type, PlnTypeInfo* orig_type2) 10 | : PlnTypeInfo(TP_ALIAS), orig_type(orig_type) 11 | { 12 | this->tname = name; 13 | this->data_type = orig_type->typeinf->data_type; 14 | this->data_size = orig_type->typeinf->data_size; 15 | this->data_align = orig_type->typeinf->data_align; 16 | } 17 | 18 | // LCOV_EXCL_START 19 | PlnTypeConvCap canCopyFrom(const string& mode, PlnVarType *src, PlnAsgnType copymode) override { 20 | BOOST_ASSERT(false); 21 | } 22 | // LCOV_EXCL_STOP 23 | }; 24 | -------------------------------------------------------------------------------- /src/test/pacode/002_varint64.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | int64 a = 1; 4 | int64 b,c,d = 2,1+2,4; 5 | int64 e,f = -1,-2; 6 | int64 h; 7 | int64 i,j = 0, 1-4; 8 | { 9 | int64 k = 3; 10 | -k -> e; 11 | } 12 | 13 | a+d -> h; 14 | e+1-f+-d+(-1) -> f; 15 | 16 | int64 k,l = add(5,6); 17 | int64 m = 1+(3+2*b)*c*4*5; 18 | 19 | printf("%d %d %d %d %d %d %d\n", h, j, f, a+b+c, k, l, m*3); 20 | 21 | a+b+c; // only calc 22 | -a; 23 | a*c; 24 | a/c; 25 | a%c; 26 | 27 | 1+2*c, 5/2*3%2, d/(-2)*5, a*b*(c-2)/(c-1) 28 | -> a,b,c,d; 29 | 30 | int64 w,x,y,z = 1,2,3,4; 31 | w-(x*y) -> z; 32 | w*(x+y) -> w; // value * (exp) case test 33 | 34 | printf("%d %d %d %d %d %d\n", a, b, c, d, w, z); 35 | 36 | 37 | func add(int64 a, b) 38 | -> int64 aa, ab 39 | { 40 | int64 c = 2; 41 | a+c-1,b+2 -> aa,ab; 42 | } 43 | -------------------------------------------------------------------------------- /src/ast/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM=pat 2 | SRCS=palanast.cpp PlnParser.cpp PlnLexer.cpp PlnAstMessage.cpp 3 | OBJS=$(notdir $(SRCS:.cpp=.o)) 4 | VPATH=.:objs:.. 5 | CXX_FLAGS= -g -O0 6 | CXX_RELEASE_FLAGS= -s -O2 7 | 8 | $(PROGRAM): $(OBJS) 9 | @echo link $(PROGRAM). 10 | @$(CXX) -o $(PROGRAM) $(addprefix objs/,$(OBJS)) -lboost_program_options 11 | @ln -fs ast/$(PROGRAM) ../$(PROGRAM) 12 | .cpp.o: 13 | @mkdir -p objs 14 | $(CXX) -std=c++11 -c $(CXX_FLAGS) $< -o objs/$@ 15 | PlnParser.cpp: PlnParser.yy 16 | bison -o $@ -r all --report-file=bison.log $< 17 | PlnLexer.cpp: PlnLexer.ll 18 | flex -o $@ $< 19 | palanast.o: PlnParser.cpp 20 | PlnParser.o: PlnLexer.h PlnParser.hpp PlnAstMessage.h 21 | palanast.o: PlnLexer.h PlnParser.hpp PlnAstMessage.h 22 | release: CXX_FLAGS=$(CXX_RELEASE_FLAGS) 23 | release: $(PROGRAM) 24 | -------------------------------------------------------------------------------- /src/models/expressions/PlnDivOperation.h: -------------------------------------------------------------------------------- 1 | /// PlnDivOperation model class declaration. 2 | /// 3 | /// @file PlnDivOperation.h 4 | /// @copyright 2017- YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnExpression.h" 7 | 8 | enum PlnDivType { 9 | DV_DIV, 10 | DV_MOD 11 | }; 12 | 13 | class PlnDivOperation : public PlnExpression 14 | { 15 | public: 16 | PlnExpression *l, *r; 17 | PlnDataPlace *quotient, *remainder; 18 | PlnDivType div_type; 19 | 20 | PlnDivOperation(PlnExpression* l, PlnExpression* r, PlnDivType dt); 21 | ~PlnDivOperation(); 22 | 23 | static PlnExpression* create(PlnExpression* l, PlnExpression* r); 24 | static PlnExpression* create_mod(PlnExpression* l, PlnExpression* r); 25 | 26 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 27 | void gen(PlnGenerator& g) override; 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /src/models/expressions/PlnArrayItem.h: -------------------------------------------------------------------------------- 1 | /// PlnArrayItem model class declaration. 2 | /// 3 | /// @file PlnArrayItem.h 4 | /// @copyright 2017-2019 YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnExpression.h" 7 | 8 | class PlnArrayItem : public PlnExpression 9 | { 10 | public: 11 | PlnExpression* array_ex; 12 | PlnExpression* index_ex; 13 | PlnArrayItem(PlnExpression *array_ex, const vector& item_ind); 14 | PlnArrayItem(PlnExpression *array_ex, vector item_ind, PlnVarType* arr_type); 15 | PlnArrayItem(PlnExpression *array_ex, PlnExpression* index_ex, PlnVarType* item_type); 16 | ~PlnArrayItem(); 17 | 18 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 19 | void gen(PlnGenerator& g) override; 20 | 21 | static vector getAllArrayItems(PlnVariable* var); 22 | }; 23 | -------------------------------------------------------------------------------- /src/test/pacode/004_regalloc.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | func func1(int64 a1, a2, a3) -> int64 4 | { 5 | return a1+a2+a3; 6 | } 7 | 8 | func many_ret_func (int64 a1) 9 | -> int64 r1, r2, r3, r4, r5, r6, r7, r8 10 | { 11 | a1+1, 2, 3 -> r1,r2,r3; 12 | 4, 5, 6 -> r4,r5,r6; 13 | 7, 8+a1 -> r7, r8; 14 | } 15 | 16 | func as_is(int64 a, int32 b) 17 | -> int32 b, int64 a 18 | { 19 | } 20 | 21 | func swap(int64 a, int32 b) 22 | -> int32 b, int64 a 23 | { 24 | } 25 | 26 | int64 a1, a2, a3 = 1, 2, 3; 27 | 28 | int64 a = func1(a1+1, func1(4,5,6)+a2, func1(7,8,9)+a3+10); 29 | int64 r1,r2,r3,r4,r5,r6,r7,r8 = many_ret_func(10); 30 | 31 | printf ("%d %d %d %d %d %d %d %d %d\n", a, r1, r2, r3, r4, r5, r6, r7, r8); 32 | 33 | int32 bb, int64 aa = as_is(64, 32); 34 | printf("%d %d", aa, bb); 35 | 36 | swap(64, 32)->bb, aa; 37 | printf(" %d %d", aa, bb); 38 | -------------------------------------------------------------------------------- /src/test/pacode/100_qsort.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | // init data. 4 | const N=10; 5 | [N]int16 data = [0,4,8,3,7,2,6,1,5,0]; 6 | // sort 7 | printf("before:"); 8 | show(data); 9 | 10 | printf("after:"); 11 | data ->> quicksort(0, N-1) 12 | ->> data 13 | -> show(); 14 | 15 | func show([N]int16 data) 16 | { 17 | i=0; 18 | while i>data, int32 left, right) 26 | -> [N]int16 data 27 | { 28 | if left >= right { return } 29 | 30 | var mid, i = left, left+1; 31 | 32 | while i<=right { 33 | if data[i] < data[left] { 34 | mid+1 -> mid; 35 | data[mid], data[i] -> data[i], data[mid]; 36 | } 37 | i+1 -> i; 38 | } 39 | data[left], data[mid] -> data[mid], data[left]; 40 | 41 | data ->> quicksort(left, mid-1) 42 | ->> quicksort(mid+1, right) 43 | ->> data; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /idea/NQueen.pa: -------------------------------------------------------------------------------- 1 | // nqueen: may not work.. 2 | const MAX_N = 30; 3 | type int aliasof int64; 4 | 5 | int n; 6 | scanf("%d" => n); 7 | 8 | [#n,n]int board = 0; 9 | int count; 10 | board.queen(0, n) -> count ; 11 | 12 | printf("answer: %d", count); 13 | 14 | func queen([#,]int >> board, x, y) 15 | -> board, int count 16 | { 17 | assert(board.size[0] == borad.size[1]); 18 | int n = borad.size[0]; 19 | 0 -> count; 20 | 21 | for xx--: x-1..1 { 22 | if board[xx, y] { 23 | return; 24 | } 25 | } 26 | 27 | for xx--: x-1..1, y--: y-1..1 { 28 | if board[xx, yy] { 29 | return; 30 | } 31 | } 32 | 33 | for xx--: x-1..1, yy: y+1..n { 34 | if board[xx, yy] { 35 | return; 36 | } 37 | } 38 | 39 | 1 -> board[x, y]; 40 | if x == n { 41 | ++count; 42 | } else { 43 | for yy: n>>1 { 44 | int c; 45 | board.queen(x+1, yy) -> c; 46 | c +-> count; 47 | } 48 | } 49 | 50 | 0 -> board[x,y]; 51 | } 52 | -------------------------------------------------------------------------------- /src/test/pacode/024_default_arg.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | const A = 1; 3 | const B = [1.1, 2.2]; 4 | 5 | intfunc(3,4); 6 | intfunc(); 7 | intfunc(3); 8 | intfunc(,3); 9 | intfunc(,); 10 | printf("\n"); 11 | 12 | intfunc2(3); 13 | intfunc2(3,4); 14 | intfunc3(,3); 15 | intfunc3(3,4); 16 | printf("\n"); 17 | 18 | arrayfunc(); 19 | arrayfunc([3,4]); 20 | arrayfunc(,[3.3,4.4]); 21 | arrayfunc([3,4],[3.3,4.4]); 22 | array2func(); 23 | 24 | // chain call 25 | printf("\n"); 26 | 3->intfunc(); 27 | [3,4]->arrayfunc(); 28 | 29 | func intfunc(int32 a=1, b=2) 30 | { 31 | printf("i%d%d", a, b); 32 | } 33 | 34 | func intfunc2(int32 a, b=2) 35 | { 36 | printf("i%d%d", a, b); 37 | } 38 | 39 | func intfunc3(int32 a=A, int64 b) 40 | { 41 | printf("i%d%d", a, b); 42 | } 43 | 44 | func arrayfunc([2]int64 a=[1,2], [2]flo64 b=B) 45 | { 46 | printf("a%d%.1f", a[1], b[1]); 47 | } 48 | 49 | func array2func([2,3]int64 a=[1,2,3][4,5,6]) 50 | { 51 | printf("a%d", a[1,1]); 52 | } 53 | -------------------------------------------------------------------------------- /idea/String.pa: -------------------------------------------------------------------------------- 1 | import 2 | 3 | // 文字リテラルの静的な文字結合は"."を使う。な場合は配列化される。 4 | string str = "This is string" 5 | . " strin2"; 6 | // ヒアドキュメント形式。<<は先頭から。<<-は1行目分のインデントは削除 7 | // エスケープシーケンスは効かない 8 | string str2 = < tarr3[1][1]; 12 | [][]int32 arr3 = tarr3; 13 | [2][]int32 arr31 = tarr3; 14 | [][3]int32 arr32 = tarr3; 15 | 16 | printf("%d%d%.1f%d%d%d\n", arr1[1], arr11[2], arr2[1,1], arr3[1][1], arr31[1][1], arr32[1][1]); 17 | 18 | // check exactlyssame. 19 | tarr1 -> arr1; 20 | tarr2 -> arr2; 21 | tarr3 -> arr3; 22 | 23 | []uint16 arr4 = [1u,2u,3u]; 24 | [3]uint16 tarr4 = arr4; 25 | [,,]flo32 arr5 = 26 | [[1.0,2.0][3.0,4.0]] 27 | [[5.0,6.0][7.0,8.0]]; 28 | 29 | [2,2,2]flo32 tarr5 = arr5; 30 | 31 | printf("%d%d%.0f%.0f", arr4[2], tarr4[2], arr5[1,1,1], tarr5[1,1,1]); 32 | 33 | []flo64 a, []int16 b = [1,2], [1,2,3]; 34 | printf(" %.0f%d", a[1], b[2]); 35 | 36 | []byte str = "abc"; 37 | [4]byte str2 = str; 38 | printf(" %s", str2); 39 | -------------------------------------------------------------------------------- /src/test/pacode/033_prireference.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | int16 a = 10; 4 | @!int16 ax = a; 5 | 6 | printf("%d ", ax); 7 | 13 -> a; 8 | printf("%d ", ax); 9 | 10 | ax + 5 -> ax; 11 | printf("%d ", a); 12 | 13 | int16 b = ax; 14 | printf("%d ", b); 15 | 16 | c = ax; // int16 17 | printf("%d ", c); 18 | 5 -> c; 19 | 20 | printf("%d ", ax); 21 | 22 | @int16 axx = ax; 23 | 11 -> a; 24 | printf("%d\n", axx); 25 | 26 | //array item 27 | [2,3]flo32 fa = [1.1, 1.2, 1.3][2.1, 2.2, 2.3]; 28 | @flo32 fx = fa[1,1]; 29 | printf("%.1f ", fx); 30 | 31 | 22.2 -> fa[1,1]; 32 | printf("%.1f ", fx); 33 | 34 | // struct 35 | type Test { 36 | int16 i16; 37 | flo32 f32; 38 | }; 39 | 40 | Test s = [ 123, 1.2 ]; 41 | @!int16 sx = s.i16; 42 | @!flo32 sf = s.f32; 43 | printf("%d %.1f ", sx, sf); 44 | 45 | 5 -> sx; 46 | 3.5 -> sf; 47 | printf("%d %.1f", s.i16, s.f32); 48 | 49 | @[?]byte str="for down cast"; 50 | arraydowmcast(str); 51 | func arraydowmcast(@[9]byte str) 52 | { 53 | printf("%c", str[4]); 54 | } 55 | -------------------------------------------------------------------------------- /idea/Error.pa: -------------------------------------------------------------------------------- 1 | ccall FILE* fopen() 2 | ! return==null; // for c language. 3 | 4 | func int MaybeError(int a) 5 | ! int error, string msg 6 | { 7 | // return -1 ; // ng 8 | 9 | if (ok) 10 | return 0; 11 | else 12 | !return 100, msg; 13 | 14 | } 15 | 16 | int success = MaybeError(10) !> err; 17 | 18 | !>err(int error, string msg) 19 | { 20 | //NG int a=success; 21 | // need to recover main returns if you will access. 22 | success = -1; 23 | } 24 | 25 | FILE* f=fopen("r", "string") !> operr; 26 | write(f, "data")!!; //ignore errors; 27 | 28 | close(f); 29 | 30 | !> operr() { 31 | printf(stderr, "file open error!\n"); 32 | exit(1); 33 | } 34 | 35 | do_somthing() !> err1; 36 | do_somthing() !> err2; 37 | 38 | !{ // errorblock. nomal flow can't into this block. 39 | @[]byte message; // can use only premitve or reference (ownership val is invaild at err1/err2) 40 | !>err1() { message = "error1" }; 41 | !>err2() { message = "error2" }; 42 | printf(stderr, "%s!\n", message); // can share the error logic. 43 | } 44 | 45 | // unit test? 46 | -------------------------------------------------------------------------------- /src/test/pacode/007_whiletest.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | ccall setenv(...); 3 | ccall mtrace(); 4 | ccall muntrace(); 5 | 6 | setenv("MALLOC_TRACE", "out/mtrace007", 1); 7 | 8 | int32 i=0; 9 | while i != 10 { 10 | printf("%d", i); 11 | i+1 -> i; 12 | } 13 | 14 | while 0 { 15 | printf("never execute"); 16 | } 17 | 18 | 3 -> i; 19 | while(i) { 20 | printf("%d", i); 21 | i-1 -> i; 22 | } 23 | 24 | printf("\n"); 25 | 26 | // break 27 | 0->i; 28 | while i<10 { 29 | printf("%d", i); 30 | if i==5 { break } 31 | i+1->i; 32 | } 33 | printf(" "); 34 | 35 | // continue 36 | 0->i; 37 | while i<5 { 38 | i+1->i; 39 | if i==3 { continue } 40 | printf("%d", i); 41 | } 42 | 43 | mtrace(); 44 | printf("\n"); 45 | 46 | // break 47 | 0->i; 48 | while i<10 { 49 | [3]int32 a; 50 | printf("%d", i); 51 | if i==5 { break } 52 | [3]int32 b; 53 | i+1->i; 54 | } 55 | 56 | printf(" "); 57 | 58 | // continue 59 | 0->i; 60 | while i<5 { 61 | [3]int32 a; 62 | i+1->i; 63 | if i==3 { continue } 64 | [3]int32 b; 65 | printf("%d", i); 66 | } 67 | 68 | muntrace(); 69 | -------------------------------------------------------------------------------- /src/models/expressions/PlnClone.h: -------------------------------------------------------------------------------- 1 | /// PlnClone model class declaration. 2 | /// 3 | /// @file PlnClone.h 4 | /// @copyright 2018-2022 YAMAGUCHI Toshinobu 5 | 6 | class PlnClone : public PlnExpression 7 | { 8 | PlnExpression *alloc_ex, *free_ex; 9 | PlnDataPlace* copy_dst_dp; 10 | PlnExpression *copy_ex; 11 | PlnExpression *src_ex; 12 | PlnExpression *dup_src_ex; 13 | vector assign_items; 14 | 15 | public: 16 | bool keep_var; 17 | bool directAssign; 18 | PlnVariable* var; 19 | PlnVariable* src_tmp_var; 20 | 21 | PlnClone(PlnDataAllocator& da, PlnExpression *src_ex, PlnVarType* var_type, bool keep_var); 22 | ~PlnClone(); 23 | 24 | void finishAlloc(PlnDataAllocator& da, PlnScopeInfo& si); 25 | void finishCopy(PlnDataAllocator& da, PlnScopeInfo& si); 26 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 27 | void finishFree(PlnDataAllocator& da, PlnScopeInfo& si); 28 | 29 | void genAlloc(PlnGenerator& g); 30 | void genCopy(PlnGenerator& g); 31 | void gen(PlnGenerator& g) override; 32 | void genFree(PlnGenerator& g); 33 | }; 34 | -------------------------------------------------------------------------------- /src/models/expressions/PlnAddOperation.h: -------------------------------------------------------------------------------- 1 | /// PlnAddOperation model class declaration. 2 | /// 3 | /// @file PlnAddOperation.h 4 | /// @copyright 2017-2019 YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnExpression.h" 7 | 8 | class PlnAddOperation : public PlnExpression 9 | { 10 | public: 11 | PlnExpression* l, *r; 12 | PlnDataPlace *ldp, *rdp; 13 | bool is_add; 14 | bool do_cross; 15 | 16 | PlnAddOperation(PlnExpression* l, PlnExpression* r, bool is_add=true); 17 | ~PlnAddOperation(); 18 | static PlnExpression* create(PlnExpression* l, PlnExpression* r); 19 | static PlnExpression* create_sub(PlnExpression* l, PlnExpression* r); 20 | 21 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 22 | void gen(PlnGenerator& g) override; 23 | }; 24 | 25 | class PlnNegative : public PlnExpression 26 | { 27 | PlnExpression *e; 28 | public: 29 | static PlnExpression* create(PlnExpression* exp); 30 | PlnNegative(PlnExpression* e); 31 | ~PlnNegative(); 32 | 33 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 34 | void gen(PlnGenerator& g) override; 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 YAMAGUCHI Toshinobu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/test/pacode/023_const_array.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | const ARR1 = [1,2,3]; 4 | const ARR2 = [ARR1, ARR1]; 5 | const ARR3 = [ARR2, ARR2]; 6 | 7 | arr1 = ARR1; 8 | arr2 = ARR2; 9 | arr3 = ARR3; 10 | 11 | [3]int32 arr11 = ARR1; 12 | [2,3]int16 arr21 = ARR2; 13 | [2,2,3]sbyte arr31 = ARR3; 14 | [2,2,3]sbyte arr32; 15 | 16 | ARR3 -> arr32; 17 | 18 | printf("%d%d%d ", arr1[0], arr2[1,1], arr3[1,1,2]); 19 | printf("%d%d%d%d ", arr11[0], arr21[1,1], arr31[1,1,2], arr32[1,1,1]); 20 | 21 | const UARR1 = [1u,2u,3u]; 22 | const FARR1 = [1.1, 2.2, 3.3]; 23 | const MIXARR = [ARR1, UARR1, [11,12,13], FARR1]; 24 | 25 | uarr1 = UARR1; 26 | farr1 = FARR1; 27 | mix = MIXARR; 28 | 29 | [4,3]flo64 ff = mix; 30 | 31 | printf("%d%.1f%.1f ", uarr1[1], farr1[2], mix[2,1]); 32 | 33 | arrayshow([1,2,3][4,5,6]); 34 | arrayshow([1u,2u,3u][4u,5u,6u]); 35 | 36 | func arrayshow([2,3]int64 a) { 37 | printf("%d%d%d", a[0,0], a[0,1], a[1,2]); 38 | } 39 | 40 | func arrayshow([2,3]uint64 a) { 41 | printf("u%d%d%d", a[0,0], a[0,1], a[1,2]); 42 | } 43 | 44 | func arrayshow([3]int64 a) { 45 | printf("NG"); 46 | } 47 | 48 | func arrayshow([2,4]uint64 a) { 49 | printf("NG"); 50 | } 51 | -------------------------------------------------------------------------------- /src/test/pacode/026_arrarr_value.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | i = 2; 4 | [2][2,3]int16 arr = [[1,2,3][4,5,6],[21,20+i,23][24,25,26]]; 5 | printf("%d %d %d\n", arr[0][0,0], arr[1][0,1], arr[1][1,2]); 6 | 7 | [[i, (1->i),1][4,5,6],[i+20,2,1][4,5,6]] 8 | -> test(); 9 | 10 | [][,]int16 arr2 = [[1,2,3][4,5,6],[7,8,9][10,11,12]]; 11 | printf("%d %d %d\n", arr2[0][0,0], arr2[1][0,1], arr2[1][1,2]); 12 | 13 | test([[1,2,3][4,5,6],[7,8,9][10,11,12]]); 14 | 15 | 2->i; 16 | [][][]int32 arr3 = [[i, (1->i),1][4,5,6],[i+20,i+10,1][4,5,6]]; 17 | printf("%d %d %d\n", arr3[0][0][0], arr3[0][0][1], arr3[1][0][0]); 18 | 19 | [2][10]byte strs = ["abc", "ABC"]; 20 | 90 -> strs[1][1]; // 'Z' 21 | printf("%s %s\n", strs[0], strs[1]); 22 | 23 | func test([2][2,3]int16 arr) 24 | { 25 | printf("%d %d %d\n",arr[0][0,0], arr[0][0,1], arr[1][0,0]); 26 | } 27 | 28 | []int64 arr4 = [4607632778762754457, 4607632778762754458]; 29 | int32 x = 1; 30 | if x < 1.1 { // comp int & flo generate RO value with shared arr4. 31 | printf("x "); 32 | } 33 | 34 | []int32 arr5 = [100, 101, 102, 103, 104]; 35 | []int32 arr6 = [102, 103]; // shared ro area case 36 | printf("%d %d", arr5[4], arr6[1]); 37 | 38 | -------------------------------------------------------------------------------- /src/ast/PlnAstMessage.cpp: -------------------------------------------------------------------------------- 1 | /// Message definitions. 2 | /// 3 | /// Manage output message descriptions in Palan parser. 4 | /// 5 | /// @file PlnAstMessage.cpp 6 | /// @copyright 2021 YAMAGUCHI Toshinobu 7 | 8 | #include "PlnAstMessage.h" 9 | #include "boost/format.hpp" 10 | 11 | using boost::format; 12 | 13 | string PlnAstMessage::getErr(PlnErrCode err_code, string arg1, string arg2) 14 | { 15 | string f; 16 | switch (err_code) { 17 | case E_CouldnotOpenFile: 18 | f = "Could not open file '%1%'."; break; 19 | default: 20 | BOOST_ASSERT(false); 21 | } 22 | 23 | string message; 24 | if (arg1 == "\x01") 25 | message = f; 26 | else if (arg2 == "\x01") 27 | message = (format(f) % arg1).str(); 28 | else 29 | message = (format(f) % arg1 % arg2).str(); 30 | 31 | return message; 32 | } 33 | 34 | const char* PlnAstMessage::getHelp(PlnHelpCode help_code) 35 | { 36 | switch (help_code) { 37 | case H_Help: 38 | return "Display this help"; 39 | case H_Output: 40 | return "Output AST json file"; 41 | case H_Indent: 42 | return "Output Indented json"; 43 | case H_Input: 44 | return "Input palan file"; 45 | } 46 | BOOST_ASSERT(false); 47 | } 48 | -------------------------------------------------------------------------------- /src/models/expressions/PlnBoolExpression.h: -------------------------------------------------------------------------------- 1 | /// PlnBoolExpression model class declaration. 2 | /// 3 | /// @file PlnBoolExpression 4 | /// @copyright 2020 YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnExpression.h" 7 | #include "../../PlnConstants.h" 8 | 9 | class PlnBoolExpression : public PlnExpression { 10 | public: 11 | int jmp_if; // -1 (no jump), 0 (jump if false), 1 (jump if true) 12 | int jmp_id; 13 | int push_mode; // data_places -1 (push result of cmp), 0 (push 0 before jump), 1 (push 1 before jump) 14 | bool is_not; // true: reverse result 15 | PlnBoolExpression(PlnExprsnType type) : PlnExpression(type), jmp_if(-1), jmp_id(-1), push_mode(-1), is_not(false) 16 | {} 17 | static PlnBoolExpression* create(PlnExpression* e); 18 | }; 19 | 20 | class PlnTrueExpression : public PlnBoolExpression 21 | { 22 | public: 23 | PlnTrueExpression(); 24 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 25 | void gen(PlnGenerator& g) override; 26 | }; 27 | 28 | class PlnFalseExpression : public PlnBoolExpression 29 | { 30 | public: 31 | PlnFalseExpression(); 32 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 33 | void gen(PlnGenerator& g) override; 34 | }; 35 | -------------------------------------------------------------------------------- /src/PlnConstants.h: -------------------------------------------------------------------------------- 1 | /// Difinition of constants to share. 2 | /// 3 | /// @file PlnConstants.h 4 | /// @copyright 2017-2016 YAMAGUCHI Toshinobu 5 | 6 | #pragma once 7 | 8 | // Data type on stack/register. 9 | enum { 10 | DT_SINT, /// Signed integer. 11 | DT_UINT, /// Unsigned integer. 12 | DT_FLOAT, /// Floating-point number. 13 | DT_OBJECT, /// Instance of object. 14 | DT_OBJECT_REF, /// Address of object. 15 | DT_UNKNOWN /// Unkown data type. Not initialized. 16 | }; 17 | 18 | // Function type. 19 | enum { 20 | FT_PLN, /// Palan standard function. 21 | FT_INLINE, /// Palan inline function. 22 | FT_C, /// C language function. 23 | FT_SYS, /// System call. 24 | FT_UNKNOWN /// Unkown function type. Not initialized. 25 | }; 26 | 27 | // Comparison type. 28 | enum PlnCmpType { 29 | CMP_EQ, 30 | CMP_NE, 31 | CMP_G, 32 | CMP_L, 33 | CMP_GE, 34 | CMP_LE, 35 | CMP_A, 36 | CMP_B, 37 | CMP_AE, 38 | CMP_BE, 39 | CMP_CONST_TRUE, 40 | CMP_CONST_FALSE 41 | }; 42 | 43 | // Type mode 44 | enum PlnTypeMode { 45 | ACCESS_MD = 0, 46 | IDENTITY_MD = 1, 47 | ALLOC_MD = 2 48 | }; 49 | 50 | enum PlnAsgnType { 51 | NO_ASGN, 52 | ASGN_COPY, 53 | ASGN_MOVE, 54 | ASGN_COPY_REF 55 | }; 56 | -------------------------------------------------------------------------------- /idea/Statement.pa: -------------------------------------------------------------------------------- 1 | 2 | for i=0..9 { 3 | print(i.str); 4 | } 5 | 6 | int i; 7 | while i<10 { 8 | print(i.str); 9 | ++i; 10 | } 11 | 12 | // break / continue 13 | for:out i=0..9 { 14 | for j; 0..9 { 15 | if (i==8 && j==5) break out; 16 | print(i.str "," j.str "\n"); 17 | } 18 | } 19 | 20 | // loop of loop 21 | for i=0..9 of j=0..9 { 22 | if (i==8 && j==5) break; 23 | } 24 | 25 | int i; 26 | while:out i<10 { 27 | ++i; 28 | for j: 0..9 { 29 | if i==8 && j==5 { continue out ; } 30 | } 31 | } 32 | 33 | // forで :の場合は型省略(上位とかぶる場合は警告) 34 | for i=1..5 { print(i.str); } 35 | for i--=5..1 { print(i.str); } 36 | // or 37 | for i:10 { // i is new variable. c: for (int i=0; i<10; i++) 38 | } 39 | // or for i<10 40 | for i=0:<10 { // i is new variable. c: for (int i=0; i<10; i++) 41 | } 42 | // or for i=1<=10 43 | for i=1:<=10 { // i is new variable. c: for (int i=1; i<=10; i++) 44 | } 45 | for i--:10 { // i is new variable. c: for (int i=9; i>=0; i--) 46 | } 47 | // or for i=9>0 48 | 49 | [10]int arr = [1..10]; 50 | for i: arr { print(i.str); } 51 | 52 | {:s 53 | for i=0..9 { 54 | s::e = i; // same as int64 e; for { i->e; 55 | } 56 | 10->e; 57 | } 58 | -------------------------------------------------------------------------------- /src/test/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | PROGRAM = tester 3 | TESTOBJS = testMain.o testBase.o basicTest.o dataAllocTest.o \ 4 | algorithmTest.o 5 | OBJS = $(filter-out ../objs/palan.o, $(wildcard ../objs/*.o)) 6 | AST = ../ast/pat 7 | POST_TESTER = cuitester 8 | POST_OBJS = cuiTestMain.o cuiTestBase.o cuiTest.o 9 | TESTCAPI_OBJ = capi4test.o 10 | 11 | .SUFFIXES: .cpp .c .o 12 | 13 | $(POST_TESTER): $(POST_OBJS) $(PROGRAM) 14 | @echo link $(POST_TESTER). 15 | @$(CXX) $(LDFLAGS) -o $(POST_TESTER) $(filter %.o, $^) -pthread 16 | 17 | $(PROGRAM): $(TESTOBJS) $(OBJS) ./pacode/*.pa $(AST) 18 | @echo link $(PROGRAM). 19 | @$(CXX) $(LDFLAGS) -o $(PROGRAM) $(filter %.o, $^) -pthread 20 | 21 | .cpp.o: 22 | $(CXX) -std=c++11 -c -g $< -pthread 23 | .c.o: 24 | $(CC) -c $< 25 | 26 | test: $(TESTCAPI_OBJ) 27 | @mkdir -p out 28 | ./$(PROGRAM) 29 | 30 | post_test: 31 | @mkdir -p out/cui 32 | ./$(POST_TESTER) 33 | 34 | force: 35 | @$(CXX) -o fpac ../objs/palan.o $(OBJS) -lboost_program_options 36 | 37 | depend: 38 | -@ $(RM) depend.inc 39 | -@ for i in $(basename $(TESTOBJS)); do $(CXX) -std=c++11 -MM $$i.cpp \ 40 | | sed "s/[_a-zA-Z0-9/][_a-zA-Z0-9/]*\.cpp//g" \ 41 | | sed "s/^\ /\t/g" >> depend.inc; done 42 | -include depend.inc 43 | -------------------------------------------------------------------------------- /src/models/expressions/PlnArrayValue.h: -------------------------------------------------------------------------------- 1 | /// Object Array value class declaration. 2 | /// 3 | /// @file PlnArrayValue.h 4 | /// @copyright 2019 YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnExpression.h" 7 | 8 | class PlnArrayValue : public PlnExpression 9 | { 10 | public: 11 | vector item_exps; 12 | bool isLiteral; 13 | bool doCopyFromStaticBuffer; 14 | 15 | PlnArrayValue(vector &exps, bool isLiteral); 16 | PlnArrayValue(const PlnArrayValue& src); 17 | 18 | PlnExpression* adjustTypes(const vector &types) override; 19 | 20 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 21 | void gen(PlnGenerator& g) override; 22 | 23 | vector getAllItems(); 24 | PlnDataPlace* getROArrayDp(PlnDataAllocator& da); // for PlnExpression 25 | PlnDataPlace* getROStructDp(PlnDataAllocator& da); // for PlnExpression 26 | 27 | /// return true - items is aixed array, false - not fixed array 28 | /// sizes - Detected array sizes. Note added 0 last. [2,3] is [2,3,0] 29 | /// item_type - Detected array element type. 30 | /// depth - for internal process (recursive call) 31 | static bool isFixedArray(const vector &items, vector &fixarr_sizes, int &item_type, int depth=0); 32 | }; 33 | 34 | -------------------------------------------------------------------------------- /src/test/pacode/101_8queen.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | const X,Y = 8,8; 4 | int32 count; 5 | [Y,X]byte board; 6 | 7 | board ->> initBoard() 8 | ->> queen(-1, -1) 9 | ->> board, count; 10 | 11 | printf("answer: %d\n", count); 12 | 13 | func initBoard([Y,X]byte >>board) 14 | -> [Y,X]byte board 15 | { 16 | y = 0; 17 | while y < Y { 18 | x = 0; 19 | while x < X { 20 | 0->board[y, x]; 21 | x++; 22 | } 23 | y++; 24 | } 25 | } 26 | 27 | func queen([Y,X]byte >>board, int32 x, y) 28 | -> [Y,X]byte board, int32 count 29 | { 30 | 0 -> count; 31 | 32 | { 33 | xx = x-1; 34 | while xx >= 0 { 35 | if board[y, xx] { return } 36 | xx--; 37 | } 38 | } 39 | 40 | { 41 | xx = x-1; 42 | yy = y-1; 43 | while xx >= 0 && yy >= 0 { 44 | if board[yy, xx] { return } 45 | xx--; 46 | yy--; 47 | } 48 | } 49 | 50 | { 51 | xx = x-1; 52 | yy = y+1; 53 | while xx >= 0 && yy < 8 { 54 | if board[yy, xx] { return } 55 | xx--; 56 | yy++; 57 | } 58 | } 59 | 60 | if x >= 0 { 1 -> board[y, x] } 61 | 62 | if x == X-1 { 63 | count++; 64 | } else { 65 | yy = 0; 66 | while yy < Y { 67 | int32 cnt; 68 | board ->> queen(x+1, yy) 69 | ->> board, cnt; 70 | cnt + count -> count; 71 | yy++; 72 | } 73 | } 74 | 75 | if x >= 0 { 0 -> board[y, x] } 76 | } 77 | -------------------------------------------------------------------------------- /src/test/capi4test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int capitest() 6 | { 7 | printf("capi called\n"); 8 | return 1; 9 | } 10 | 11 | typedef struct { 12 | int id; 13 | int status; 14 | char name[10]; 15 | } TestDb; 16 | 17 | int topen(const char* name, TestDb** tdb) 18 | { 19 | if (strlen(name) > 9) 20 | return 1; 21 | *tdb = malloc(sizeof(TestDb)); 22 | if (!*tdb) 23 | return 1; 24 | (*tdb)->id = 1234; 25 | strcpy((*tdb)->name, name); 26 | (*tdb)->status = 99; 27 | 28 | return 0; 29 | } 30 | 31 | int topen2(const char* name, int* stat, TestDb** tdb) 32 | { 33 | *stat = 999; 34 | return topen(name, tdb); 35 | } 36 | 37 | int tgetId(TestDb* tdb) 38 | { 39 | return tdb->id; 40 | } 41 | 42 | const char* tgetName(TestDb* tdb) 43 | { 44 | return tdb->name; 45 | } 46 | 47 | void tclose(TestDb *tdb) 48 | { 49 | if (!tdb) 50 | return; 51 | 52 | if (tdb->id != 1234) { 53 | printf("tclose: unrecognized id.\n"); 54 | } 55 | if (tdb->status != 99) { 56 | printf("tclose: unrecognized status.\n"); 57 | } 58 | 59 | free(tdb); 60 | } 61 | 62 | void tprintparray(int64_t** parray, int num1, int num2) 63 | { 64 | int i, j; 65 | for (i=0; i int32; 2 | ccall setenv(...); 3 | ccall mtrace(); 4 | ccall muntrace(); 5 | 6 | setenv("MALLOC_TRACE", "out/mtrace035", 1); 7 | 8 | type A { 9 | int64 a; 10 | int64 b; 11 | }; 12 | 13 | type B { 14 | int64 a; 15 | int64 b; 16 | A o; 17 | }; 18 | 19 | { 20 | // init test 21 | $A a_stk = [1,2]; 22 | A a_heap = [3,4]; 23 | $A a2_stk = a_heap; 24 | $A a3_stk; 25 | 26 | // member access 27 | a_stk.b + a2_stk.b -> a3_stk.a; 28 | 29 | f1(a_stk); 30 | f1(a2_stk); 31 | f1(a3_stk); 32 | 33 | // assignment 34 | a_stk -> a3_stk; 35 | f1(a3_stk); 36 | a_stk -> a_heap; 37 | f1(a_heap); 38 | 39 | [5,6] -> a_stk; 40 | f1(a_stk); 41 | f2(a2_stk) -> a_stk; 42 | printf(" %d", a_stk.b); 43 | } 44 | 45 | int64 x = 99; 46 | mtrace(); 47 | { 48 | $A a = [1,2]; 49 | $B b; 50 | 51 | a->b.o; 52 | b.o.b -> x; 53 | } 54 | muntrace(); 55 | printf(" %d", x); 56 | 57 | // test->test2; 58 | // test2->testx; 59 | // testx->test2; 60 | 61 | // $B b; // NG 62 | 63 | // 4->zz[2]; 64 | 65 | // int64 x = 1; 66 | // 3->test.b; 67 | // f2(xx); 68 | 69 | // need other tests.. 70 | // test!->f3(); 71 | // testx.f3().f3(); 72 | 73 | 74 | func f1(@A a) 75 | { 76 | printf("%d", a.a); 77 | } 78 | 79 | func f2(@A a) -> A b 80 | { 81 | a.a * 4 -> b.a; 82 | a.b * 4 -> b.b; 83 | } 84 | -------------------------------------------------------------------------------- /src/models/PlnVariable.h: -------------------------------------------------------------------------------- 1 | /// Variable model class declaration. 2 | /// 3 | /// @file PlnVariable.h 4 | /// @copyright 2017-2021 YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnModel.h" 7 | 8 | class PlnVariable { 9 | public: 10 | string name; 11 | PlnVarType* var_type; 12 | PlnDataPlace* place; 13 | PlnVariable* container; // for indirect variable. a[2] -> container is a. 14 | bool is_tmpvar; 15 | bool is_indirect; 16 | bool is_global; 17 | 18 | struct { 19 | vector *sizes; 20 | } inf ; 21 | 22 | PlnLoc loc; 23 | 24 | PlnVariable(): var_type(NULL), place(NULL), container(NULL), 25 | is_tmpvar(false), is_indirect(false), is_global(false) {} 26 | 27 | PlnExpression* getFreeEx(); 28 | PlnExpression* getInternalFreeEx(); 29 | static PlnVariable* createTempVar(PlnDataAllocator& da, PlnVarType* var_type, const string& name); 30 | }; 31 | 32 | class PlnAssignItem; 33 | 34 | // Variable initialization 35 | class PlnVarInit { 36 | struct VarInitInf { 37 | PlnVariable* var; 38 | PlnExpression* alloc_ex; 39 | PlnExpression* internal_alloc_ex; 40 | }; 41 | vector varinits; 42 | vector assgin_items; 43 | 44 | public: 45 | PlnVarInit(vector& vars, vector *inits=NULL); 46 | ~PlnVarInit(); 47 | 48 | void finish(PlnDataAllocator& da, PlnScopeInfo& si); 49 | void gen(PlnGenerator& g); 50 | }; 51 | -------------------------------------------------------------------------------- /src/models/PlnLoopStatement.h: -------------------------------------------------------------------------------- 1 | /// Loop statement model classes declaration. 2 | /// 3 | /// @file PlnLoopStatement.h 4 | /// @copyright 2018-2019 YAMAGUCHI Toshinobu 5 | 6 | #include "PlnStatement.h" 7 | 8 | class PlnBoolExpression; 9 | class PlnWhileStatement : public PlnStatement 10 | { 11 | public: 12 | PlnBoolExpression* condition; 13 | 14 | int jmp_start_id, jmp_end_id; 15 | PlnDataPlace* cond_dp; 16 | 17 | PlnWhileStatement(PlnExpression* condition, PlnBlock* block, PlnBlock* parent); 18 | PlnWhileStatement(const PlnWhileStatement &) = delete; 19 | ~PlnWhileStatement(); 20 | 21 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 22 | void gen(PlnGenerator& g) override; 23 | }; 24 | 25 | class PlnBreakStatement : public PlnStatement 26 | { 27 | public: 28 | int jmp_id; 29 | PlnStatement* target_stmt; 30 | vector free_vars; 31 | 32 | PlnBreakStatement(PlnStatement* target_stmt); 33 | 34 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 35 | void gen(PlnGenerator& g) override; 36 | }; 37 | 38 | class PlnContinueStatement : public PlnStatement 39 | { 40 | public: 41 | int jmp_id; 42 | PlnStatement* target_stmt; 43 | vector free_vars; 44 | 45 | PlnContinueStatement(PlnStatement* target_stmt); 46 | 47 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 48 | void gen(PlnGenerator& g) override; 49 | }; 50 | 51 | -------------------------------------------------------------------------------- /src/test/pacode/008_iftest.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | func elif(int32 i) 4 | { 5 | if i == 0 { 6 | printf("[if]"); 7 | } else if (i == 1) { 8 | printf("[elif]"); 9 | } else if 2 >= i { 10 | printf("[elif2]"); 11 | } else { 12 | printf("[else]"); 13 | } 14 | } 15 | 16 | elif(0); 17 | elif(1); 18 | elif(2); 19 | elif(3); 20 | 21 | if 1 { printf("[true]"); } 22 | if 0 { printf("[false]"); } 23 | 24 | printf("\n"); 25 | 26 | int32 i = 0; 27 | while i < 3 { 28 | printf("%d", i); 29 | 30 | if i == 1 { printf("=="); } 31 | if i != 1 { printf("!="); } 32 | if i < 1 { printf("<"); } 33 | if i > 1 { printf(">"); } 34 | if i <= 1 { printf("<="); } 35 | if i >= 1 { printf(">="); } 36 | 37 | i+1 -> i; 38 | } 39 | 40 | printf("\n"); 41 | byte b = 255; 42 | 43 | if b > 1 { printf("[us1]"); } 44 | if 1u < b { printf("[uu1]"); } 45 | 46 | if b <= 1 { printf("[us2]"); } 47 | if 1u <= b { printf("[uu2]"); } 48 | 49 | 50 | if b+1 > b-1 { printf(">"); } 51 | 52 | 1->i; 53 | 54 | if i<=2==1 { printf("t"); } 55 | else { printf("f"); } 56 | if 1>=2<1 { printf("t"); } 57 | else { printf("f"); } 58 | printf("%d%d%d",i<1,i<2,b<=1u); 59 | 60 | if 2>1 { printf("t"); } else { printf("f"); } 61 | if 2u>=2u { printf("t"); } else { printf("f"); } 62 | if 1u>=2u { printf("t"); } else { printf("f"); } 63 | if 1u==1 { printf("t"); } else { printf("f"); } 64 | if 1u!=1 { printf("t"); } else { printf("f"); } 65 | -------------------------------------------------------------------------------- /src/test/pacode/005_intpromotion.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | sbyte sb, byte ub = -128, 255; 4 | int16 sd, uint16 ud = -32768, 65535; 5 | int32 sl, uint32 ul = -2147483648, 4294967295; 6 | int64 sq = -9223372036854775808; 7 | uint64 uq, uq2 = 18446744073709551615u, 1u; 8 | 9 | printf("%d %d %d %d\n", sb, ub, sd, ud); 10 | printf("%d %u\n", sl, ul); 11 | printf("%lld\n", sq); 12 | printf("%llu\n", uq); 13 | 14 | // integer promotion 15 | uint64 udiv = uq / 3u; 16 | int64 idiv = uq / 3; 17 | uint64 umod; 18 | int64 imod; 19 | 20 | printf("%llu %lld\n", udiv, idiv); 21 | uq % 3u -> umod; 22 | uq % 3 -> imod; 23 | printf("%lld %lld\n", umod, imod); 24 | 25 | 18446744073709551615u - 18446744073709551614u -> uq; 26 | 9223372036854775807u + 9223372036854775807u -> uq2; 27 | 28 | 29 | printf("%llu %llu", uq, uq2); 30 | 31 | 18446744073709551615u -> uq2; 32 | uq2 / 9223372036854775807u -> uq2; 33 | printf(" %llu", uq2); 34 | 35 | 9223372036854775807u -> uq2; 36 | 18446744073709551615u / uq2 -> uq2; 37 | printf(" %llu\n", uq2); 38 | 39 | sq + 1 + 2 -> sq; 40 | uq + 1u + 2u -> uq; 41 | printf("%lld %llu\n", sq, uq); 42 | 43 | sq - 1 - 2 -> sq; 44 | uq - 1u - 2u -> uq; 45 | 46 | printf("%lld %llu\n", sq, uq); 47 | 48 | 3u * 2u -> uq; 49 | uq * 2u * 3u -> uq; 50 | 51 | 35u / 2u -> uq2; 52 | 4 + uq2 / 2u / 3u / 2 * 3 -> uq2; 53 | 35u % 9u -> ul; 54 | printf("%llu %llu %lu\n", uq, uq2, ul); 55 | 56 | printf("%lld\n", 9223372036854775807); 57 | 58 | 59 | -------------------------------------------------------------------------------- /idea/ChainCall.pa: -------------------------------------------------------------------------------- 1 | // assignment 2 | 1,2->a,b; 3 | abc(1,2)->a,b; 4 | 5 | // number of L and R values must be L>=R. 6 | abc(1,2)->a; 7 | 8 | // func call 9 | 1, 2 -> abc(); 10 | // func call with arg 11 | 1, 2 -> abc(3); 12 | 1, ff(2) -> abc(3); // c=3 13 | 1, ff(2) -> abc(3->a); // a=3, b=1, c=ff(2) 14 | 1, ff(2) -> abc($2,$1->a,b); 15 | 1, ff(2) -> abc($2,$1); 16 | ff(3), ff(2) -> abc(); 17 | 18 | // chain call:only one function call. 19 | 1, a -> abc(d) -> xyz(); 20 | 1, a -> abc(d) -> xyz() -> a, b; 21 | 1, a -> abc(d) -> a, b -> f(); 22 | // same 23 | (1, a -> abc(d) -> a, b) -> f(); 24 | // ok func args 25 | 1, a -> abc(ff(d)) -> xyz(); 26 | 27 | // NG: chain call with assgin 28 | 1, a -> abc(d) -> f(), b; 29 | 1, a -> abc(d) -> b, f() 30 | // use temp var instead 31 | 1, a -> abc(d) -> a, b -> f(); 32 | 1, a -> abc(d) -> a, b -> f($1->a); 33 | 34 | // NG: chain to multi func 35 | 1, a -> abc(d) -> ff(), f() 36 | 37 | // NG: f() return void 38 | 1, a -> abc(d) -> f() -> xyz(); 39 | 40 | 41 | // can use anonymouse func with {} for special case 42 | 1, a -> {return $1,$0,b} -> abc(); 43 | 1, a -> { $1->b; return f($1); } -> abc(); 44 | 45 | Object o, o2; 46 | o, o2 ->> of($2,3->>o2,a); 47 | 48 | func abc(int32 a, b, c=0) 49 | -> int32 d, e 50 | { 51 | } 52 | 53 | func xyz(int32 a, b, c=0) 54 | -> int32 d, e 55 | { 56 | } 57 | 58 | func f(int32 a) 59 | { 60 | } 61 | 62 | func ff(int32 a) -> a 63 | { 64 | } 65 | 66 | func objf(Object >>o, >>o2, a) 67 | { 68 | } 69 | -------------------------------------------------------------------------------- /src/PlnScopeStack.cpp: -------------------------------------------------------------------------------- 1 | /// Scope management class definition. 2 | /// 3 | /// @file PlnScopeStack.cpp 4 | /// @copyright 2018-2019 YAMAGUCHI Toshinobu 5 | 6 | #include 7 | #include 8 | 9 | #include "PlnConstants.h" 10 | #include "PlnModel.h" 11 | #include "models/PlnType.h" 12 | #include "models/PlnVariable.h" 13 | #include "PlnScopeStack.h" 14 | 15 | bool PlnScopeInfo::exists_current(PlnVariable* v) 16 | { 17 | PlnScopeItem si = scope.back(); 18 | auto ov = std::find_if(owner_vars.begin(), owner_vars.end(), 19 | [v, si](PlnScopeVarInfo &vi) { return vi.var == v && vi.scope == si; } ); 20 | return ov != owner_vars.end(); 21 | } 22 | 23 | void PlnScopeInfo::set_lifetime(PlnVariable* v, PlnVarLifetime lt) 24 | { 25 | BOOST_ASSERT(v->var_type->mode[IDENTITY_MD] == 'm'); 26 | auto ov = std::find_if(owner_vars.rbegin(), owner_vars.rend(), 27 | [v](PlnScopeVarInfo &vi) { return vi.var == v; } ); 28 | 29 | BOOST_ASSERT(ov != owner_vars.rend()); 30 | (*ov).lifetime = lt; 31 | } 32 | 33 | PlnVarLifetime PlnScopeInfo::get_lifetime(PlnVariable* v) 34 | { 35 | BOOST_ASSERT(v->var_type->mode[IDENTITY_MD] == 'm'); 36 | auto ov = std::find_if(owner_vars.rbegin(), owner_vars.rend(), 37 | [v](PlnScopeVarInfo &vi) 38 | { 39 | if (vi.var == v) return true; 40 | else return vi.var == v->container; 41 | } ); 42 | 43 | 44 | if (ov == owner_vars.rend()) 45 | return VLT_NOTEXIST; 46 | 47 | return (*ov).lifetime; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/models/expressions/PlnBoolOperation.h: -------------------------------------------------------------------------------- 1 | /// PlnBoolOperation model class declaration. 2 | /// 3 | /// @file PlnBoolOperation.h 4 | /// @copyright 2018-2020 YAMAGUCHI Toshinobu 5 | 6 | #include "PlnCmpOperation.h" 7 | 8 | class PlnBoolOperation : public PlnBoolExpression 9 | { 10 | protected: 11 | PlnBoolExpression *l, *r; 12 | int end_jmp_id; 13 | 14 | public: 15 | PlnBoolOperation(PlnBoolExpression* l, PlnBoolExpression* r, PlnExprsnType type); 16 | PlnBoolOperation(const PlnBoolOperation&) = delete; 17 | ~PlnBoolOperation(); 18 | 19 | static PlnExpression* create(PlnExpression* l, PlnExpression* r, PlnExprsnType type); 20 | static PlnExpression* createNot(PlnExpression* e); 21 | }; 22 | 23 | class PlnAndOperation : public PlnBoolOperation 24 | { 25 | public: 26 | PlnAndOperation(PlnBoolExpression* l, PlnBoolExpression* r) 27 | : PlnBoolOperation(l, r, ET_AND) { }; 28 | PlnAndOperation(const PlnAndOperation&) = delete; 29 | ~PlnAndOperation() { }; 30 | 31 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 32 | void gen(PlnGenerator& g) override; 33 | }; 34 | 35 | class PlnOrOperation : public PlnBoolOperation 36 | { 37 | public: 38 | PlnOrOperation(PlnBoolExpression* l, PlnBoolExpression* r) 39 | : PlnBoolOperation(l, r, ET_OR) { }; 40 | PlnOrOperation(const PlnOrOperation&) = delete; 41 | ~PlnOrOperation() { }; 42 | 43 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 44 | void gen(PlnGenerator& g) override; 45 | }; 46 | 47 | -------------------------------------------------------------------------------- /src/models/PlnStatement.h: -------------------------------------------------------------------------------- 1 | /// PlnStatement model class declaration. 2 | /// 3 | /// @file PlnStatement.h 4 | /// @copyright 2017-2019 YAMAGUCHI Toshinobu 5 | #pragma once 6 | #include "../PlnModel.h" 7 | 8 | // Statement: Expression | Block 9 | enum PlnStmtType { 10 | ST_EXPRSN, 11 | ST_VARINIT, 12 | ST_BLOCK, 13 | ST_RETURN, 14 | ST_WHILE, 15 | ST_BREAK, 16 | ST_CONTINUE, 17 | ST_IF 18 | }; 19 | 20 | class PlnStatement { 21 | public: 22 | PlnStmtType type; 23 | PlnBlock* parent; 24 | union { 25 | PlnExpression* expression; 26 | PlnVarInit* var_init; 27 | PlnBlock *block; 28 | } inf; 29 | PlnLoc loc; 30 | 31 | PlnStatement() {}; 32 | PlnStatement(PlnExpression *exp, PlnBlock* parent); 33 | PlnStatement(PlnVarInit* var_init, PlnBlock* parent); 34 | PlnStatement(PlnBlock* block, PlnBlock* parent); 35 | virtual ~PlnStatement(); 36 | 37 | virtual void finish(PlnDataAllocator& da, PlnScopeInfo& si); 38 | virtual void gen(PlnGenerator& g); 39 | }; 40 | 41 | class PlnClone; 42 | class PlnReturnStmt : public PlnStatement 43 | { 44 | public: 45 | PlnFunction *function; 46 | vector expressions; 47 | vector clones; 48 | vector dps; 49 | vector free_vars; 50 | 51 | PlnReturnStmt(vector &retexp, PlnBlock* parent); // throw PlnCompileError 52 | ~PlnReturnStmt(); 53 | 54 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 55 | void gen(PlnGenerator& g) override; 56 | }; 57 | 58 | -------------------------------------------------------------------------------- /src/test/pacode/013_chaincall.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | // primitive 4 | int32 a, b, c, d; 5 | [3]int32 aa, bb; 6 | 7 | //case1 8 | 9->a; 9 | 3,a -> inc()-> inc() -> a, b; 10 | printf("%d %d\n", a, b); 11 | 12 | //case2 13 | 1->a; 14 | a -> add(3)-> add(4) -> a; 15 | printf("%d ", a); 16 | 3->aa[1]->aa[2]; 17 | aa[1] -> add(2)-> add(aa[2]) -> aa[0]; 18 | printf("%d\n", aa[0]); 19 | 20 | //case3 21 | inc(3,2) -> add() -> aa[2] -> add(3) -> aa[0]; 22 | printf("%d\n", aa[0]); 23 | 24 | func inc(int32 a, b) -> int32 a, b 25 | { 26 | printf("%d %d ", a, b); 27 | a+1->a; 28 | b+1->b; 29 | } 30 | 31 | func add(int32 a, int32 b) -> int32 a 32 | { 33 | printf("%d ", a); 34 | a+b->a; 35 | } 36 | 37 | // object 38 | [3]int64 i, j; 39 | [2][3]int64 ii, jj; 40 | 41 | // deep copy 42 | 3->i[1]; 43 | i -> ocopy(3) -> ii[1] 44 | ->ocopy(2) -> ocopy(1) -> j; 45 | printf("%d %d", j[1], ii[1][1]); 46 | 47 | i ->> omove(3) ->> j 48 | ->> omove(1) ->> omove(5) ->> j; 49 | printf(" %d\n", j[1]); 50 | 51 | 1->ii[0][1]; 52 | ii[0][1] -> add(3)-> add(4) 53 | -> ii[0][2]-> add(ii[0][1]) -> ii[1][0]; 54 | // 1 8 9 55 | printf("%d %d %d\n", ii[0][1],ii[0][2],ii[1][0]); 56 | 57 | func ocopy([3]int64 a, int32 b) -> [3]int64 a 58 | { 59 | a[1] + b -> a[1]; 60 | } 61 | 62 | func omove([3]int64 >>a, int32 b) -> [3]int64 a 63 | { 64 | a[1] + b -> a[1]; 65 | } 66 | 67 | func ret_chain() -> int32 i, j, int16 l 68 | { 69 | 1,2,3 -> i,j,l; 70 | } 71 | 72 | "%d %d %d\n", ret_chain() -> printf(); 73 | 74 | -------------------------------------------------------------------------------- /src/models/expressions/assignitem/PlnAssignPrimitiveItem.h: -------------------------------------------------------------------------------- 1 | /// Assignment Item class definition. 2 | /// 3 | /// Src value don't need to be clear. 4 | /// 5 | /// @file PlnAssignPrimitiveItem.h 6 | /// @copyright 2018-2020 YAMAGUCHI Toshinobu 7 | 8 | class PlnAssignPrimitiveItem : public PlnAssignItem { 9 | PlnExpression* src_ex; 10 | PlnDstItem* dst_item; 11 | 12 | public: 13 | PlnAssignPrimitiveItem(PlnExpression* ex) : src_ex(ex), dst_item(NULL) { 14 | } 15 | 16 | ~PlnAssignPrimitiveItem() { 17 | delete dst_item; 18 | } 19 | 20 | void addDstEx(PlnExpression* ex, bool need_save) override { 21 | BOOST_ASSERT(dst_item == NULL); 22 | BOOST_ASSERT(ex->values[0].type == VL_VAR); 23 | //BOOST_ASSERT(ex->values[0].getVarType()->data_type() != DT_OBJECT_REF); 24 | // BOOST_ASSERT(ex->values[0].getVarType()->mode[ALLOC_MD] != 'r'); 25 | dst_item = PlnDstItem::createDstItem(ex, need_save); 26 | } 27 | 28 | int addDataPlace(vector &data_places, int start_ind) override { 29 | dst_item->place = data_places[start_ind]; 30 | return start_ind + 1; 31 | } 32 | 33 | void finishS(PlnDataAllocator& da, PlnScopeInfo& si) override { 34 | PlnFinishRole fr = dst_item->setSrcEx(da, si, src_ex); 35 | BOOST_ASSERT(fr==FINISH_BY_ASSIGNITEM); 36 | src_ex->finish(da, si); 37 | } 38 | 39 | void finishD(PlnDataAllocator& da, PlnScopeInfo& si) override { 40 | dst_item->finish(da, si); 41 | } 42 | 43 | void genS(PlnGenerator& g) override { 44 | src_ex->gen(g); 45 | } 46 | 47 | void genD(PlnGenerator& g) override { 48 | dst_item->gen(g); 49 | } 50 | }; 51 | 52 | -------------------------------------------------------------------------------- /src/test/pacode/037_directobj_arr.pa: -------------------------------------------------------------------------------- 1 | ccall printf(@[?]byte format, ...) -> int32; 2 | 3 | type stct { 4 | int32 a, b; 5 | flo32 f; 6 | }; 7 | 8 | type stct_stct { 9 | stct s; 10 | int32 c, d; 11 | }; 12 | 13 | int32 o1,o3,o4,o5,o6,o7,o8,o9,o10,o10_2,o11; 14 | flo32 f11; 15 | 16 | $[10]int32 a1; 17 | 10 -> a1[5]; 18 | { 19 | $[10]int32 a2; 20 | a1 -> a2; 21 | a2[5] -> o1; 22 | } 23 | 24 | { 25 | $[3,2]int32 a3 = [1,2][3,4][5,6]; 26 | a3[2,1] -> o3; 27 | } 28 | 29 | { 30 | 31 | $[3][2]int32 a4 = [1,2][3,4][5,6]; 32 | a4[2][1] -> o4; 33 | } 34 | 35 | { 36 | $[3]stct a5 = [1,2,1.1][3,4,1.2][5,6,1.3]; 37 | a5[1].b -> o5; 38 | } 39 | 40 | { 41 | [3]$[2]int32 a6 = [1,2][3,4][5,6]; 42 | a6[2][1] -> o6; 43 | } 44 | 45 | { 46 | [3][2]$[1]int32 a7 = [[1][2]][[3][4]][[5][6]]; 47 | a7[2][1][0] -> o7; 48 | } 49 | 50 | { 51 | [3]$[2]$[1]int32 a8 = [[1][2]][[3][4]][[5][6]]; 52 | a8[2][1][0] -> o8; 53 | } 54 | 55 | { 56 | [3]$[2][1]int32 a9 = [[1][2]][[3][4]][[5][6]]; 57 | a9[2][1][0] -> o9; 58 | } 59 | 60 | { 61 | [3]$stct a10 = [1,2,1.1][3,4,1.2][5,6,1.3]; 62 | a10[2].b -> o10; 63 | 64 | $stct aa; 65 | int32 x = 7; 66 | ([x,8,1.5] -> a10[0]) -> aa; 67 | aa.a -> o10_2; 68 | } 69 | 70 | { 71 | [3]$stct_stct a11 = [[1,2,1.1],3,4] 72 | [[5,6,1.2],7,8] 73 | [[9,10,1.3],11,12]; 74 | a11[2].s.b -> o11; 75 | a11[2].s.f -> f11; 76 | } 77 | 78 | printf("%d %d %d %d %d ", o1, o3, o4, o5, o6); 79 | printf("%d %d %d %d %d %d %.1f\n", o7, o8, o9, o10, o10_2, o11, f11); 80 | 81 | { 82 | [3]$[10]byte names = ["Alice","Bob","Ken"]; 83 | printf("%s,%s,%s", names[0], names[1], names[2]); 84 | } 85 | 86 | -------------------------------------------------------------------------------- /src/test/pacode/039_dirctallocmember.pa: -------------------------------------------------------------------------------- 1 | ccall printf(@[?]byte format, ...) -> int32; 2 | 3 | type A { 4 | $[10]int32 a; 5 | int32 b; 6 | }; 7 | 8 | type B { 9 | int32 c; 10 | $A aa; 11 | int32 z; 12 | }; 13 | // Assignment. 14 | A x; 15 | 16 | 3 -> x.a[9] ; 17 | printf("%d ", x.a[9]); 18 | 19 | B bb; 20 | 21 | 4 -> bb.aa.a[5]; 22 | 23 | [10]int32 t = bb.aa.a; 24 | 25 | printf("%d ", t[5]); 26 | 27 | // Init by read-only array value. 28 | A a2 = [[1,2,3,4,5,6,7,8,9,0],99]; 29 | 30 | printf("%d %d ", a2.a[9], a2.b); 31 | 32 | B b2 = [77, [[1,2,3,4,5,6,7,8,9,0],99], 88]; 33 | 34 | printf("%d %d %d ", b2.aa.a[8], b2.aa.b, b2.z); 35 | 36 | type C { 37 | int32 a; 38 | int32 b; 39 | }; 40 | 41 | [3]$C arr = [1,2][3,4][5,6]; 42 | printf("%d ", arr[1].b); 43 | 44 | [11,12][21,22][31,32] -> arr; 45 | printf("%d\n", arr[1].b); 46 | 47 | int32 i1, i2 = 4, 9; 48 | i1 -> bb.aa.a[i2]; 49 | printf("%d ", bb.aa.a[i2]); 50 | 51 | [[1,2,3,4,5,6,7,8,i1,0],i2] -> a2; 52 | 53 | printf("%d %d ", a2.a[8], a2.b); 54 | 55 | 56 | // from sample raytracer bug. 57 | type ptr = int64; 58 | type jpeg_error_mgr { 59 | ptr error_exit; 60 | }; 61 | 62 | type inc_obj_ref { 63 | [4]ptr arr; 64 | }; 65 | 66 | type jpeg_compress_struct { 67 | jpeg_error_mgr err;// struct jpeg_error_mgr *err; 68 | ptr comp_info; // jpeg_component_info *comp_info; 69 | $[4]ptr quant_tbl_ptrs; 70 | $inc_obj_ref dummy; 71 | }; 72 | 73 | jpeg_compress_struct js; 74 | 75 | type User { 76 | int64 id; 77 | $[16]byte name1, name2; 78 | int16 age; 79 | }; 80 | 81 | $User u = [101, "Alice","Bob", 12]; 82 | 83 | printf("%s,%s,%d", u.name1, u.name2, u.age); 84 | 85 | -------------------------------------------------------------------------------- /src/test/pacode/015_assignment2.pa: -------------------------------------------------------------------------------- 1 | // Assignment swap values tests 2 | ccall printf(...); 3 | 4 | int32 i, j, k = 1, 2, 3; 5 | 6 | // simple primitive copy case 7 | i, j -> j, i; 8 | printf("%d %d ", i, j); 9 | 10 | 1,2,3 -> i,j,k; 11 | i,(j->i) -> j,k; 12 | printf("%d %d %d\n", i,j,k); 13 | 14 | [3]int32 a, b, c = arr(0), arr(3), arr(6); 15 | 16 | // mixed copy case 17 | b, a[1] -> a, i; 18 | printf("%d %d ", a[1], i); 19 | 20 | 1,2,3 -> i,j,k; 21 | i,j -> k,a[1]; 22 | printf("%d %d ", a[1], k); 23 | 24 | 1,2,3 -> i,j,k; 25 | i,(j->a[1])->j,k; 26 | printf("%d %d %d\n", a[1],j, k); 27 | 28 | arr(0) -> a; 29 | 30 | // deep copy case 31 | a, b -> b, a; 32 | printf("%d %d\n", a[1], b[1]); 33 | 34 | // complex case (assign in assign) 35 | arr(0) -> a; 36 | arr(3) -> b; 37 | a[1], c[(9->a[1])-8] -> b[2], a[2]; 38 | printf("%d %d %d\n", a[1],a[2],b[2]); 39 | 40 | // move test 41 | arr(0) -> a; 42 | arr(3) -> b; 43 | a, b ->>b, >>a; 44 | printf("%d %d ", a[1], b[1]); 45 | 46 | // move self (do nothing) 47 | a ->> a; 48 | printf("%d\n", a[1]); 49 | 50 | [2][3]int32 aa, bb; 51 | arr(0) -> aa[1]; 52 | arr(3) -> bb[0]; 53 | 54 | aa[1], bb[0] ->> bb[0], >>aa[1]; 55 | printf("%d %d ", aa[1][1], bb[0][1]); 56 | 57 | // self move 58 | aa[1] ->> aa[1]; 59 | printf("%d ", aa[1][1]); 60 | 61 | // mixed 62 | arr(0) -> aa[1]; 63 | arr(3) -> b; 64 | aa[1], b ->>b, >>aa[1]; 65 | printf("%d %d ", aa[1][1], b[1]); 66 | 67 | { 68 | b, aa[1] ->> aa[1], >>b; 69 | printf("%d %d\n", aa[1][1], b[1]); 70 | } 71 | 72 | func arr(int32 base) -> [3]int32 a 73 | { 74 | int32 i = 0; 75 | while (i < 3) { 76 | base + i -> a[i]; 77 | i+1 -> i; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/PlnModel.h: -------------------------------------------------------------------------------- 1 | /// All model classes declaration. 2 | /// 3 | /// @file PlnModel.h 4 | /// @copyright 2017 YAMAGUCHI Toshinobu 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using std::string; 15 | using std::vector; 16 | using std::ostream; 17 | using std::cout; 18 | using std::endl; 19 | using std::unique_ptr; 20 | using std::to_string; 21 | 22 | // parser 23 | class PlnScopeItem; 24 | class PlnScopeInfo; 25 | 26 | // model 27 | class PlnModule; 28 | class PlnFunction; 29 | class PlnBlock; 30 | class PlnStatement; 31 | class PlnVarInit; 32 | class PlnReturnStmt; 33 | class PlnExpression; 34 | class PlnValue; 35 | class PlnTypeInfo; 36 | class PlnVarType; 37 | class PlnVariable; 38 | class PlnParameter; 39 | 40 | class PlnReadOnlyData; 41 | class PlnArrayItem; 42 | class PlnDataAllocator; 43 | class PlnDataPlace; 44 | 45 | // generator 46 | class PlnGenerator; 47 | class PlnGenEntity; 48 | 49 | // Code location infomation 50 | struct PlnLoc { 51 | uint32_t begin_line; 52 | uint32_t end_line; 53 | uint16_t begin_col; 54 | uint16_t end_col; 55 | int16_t fid; 56 | PlnLoc() : fid(-1) {}; 57 | PlnLoc(vector a) 58 | : fid(a[0]), begin_line(a[1]), begin_col(a[2]), end_line(a[3]), end_col(a[4]) {}; 59 | string dump() 60 | { 61 | if (fid >= 0) 62 | return to_string(fid) 63 | + ":" +to_string(begin_line) 64 | + "-" +to_string(end_line); 65 | return "none"; 66 | }; 67 | 68 | }; 69 | 70 | // Utilities 71 | template 72 | inline void deleteInstatnces(vector objs) { 73 | for (auto obj: objs) delete obj; 74 | } 75 | -------------------------------------------------------------------------------- /src/models/types/PlnStructType.h: -------------------------------------------------------------------------------- 1 | /// Structure type class declaration. 2 | /// 3 | /// @file PlnStructType.h 4 | /// @copyright 2019-2022 YAMAGUCHI Toshinobu 5 | 6 | class PlnStructMemberDef { 7 | public: 8 | PlnVarType* type; 9 | string name; 10 | int offset; 11 | 12 | PlnStructMemberDef(PlnVarType *type, const string& name); 13 | }; 14 | 15 | class PlnStructTypeInfo : public PlnTypeInfo { 16 | public: 17 | vector members; 18 | bool has_heap_member; 19 | PlnFunction* alloc_func; 20 | PlnFunction* internal_alloc_func; 21 | PlnFunction* free_func; 22 | PlnFunction* internal_free_func; 23 | PlnFunction* copy_func; 24 | 25 | PlnStructTypeInfo(const string &name, vector &members, PlnBlock* parent, const string& default_mode); 26 | ~PlnStructTypeInfo(); 27 | 28 | PlnTypeConvCap canCopyFrom(const string& mode, PlnVarType *src, PlnAsgnType copymode) override; 29 | PlnVarType* getVarType(const string& mode) override; 30 | }; 31 | 32 | class PlnStructVarType : public PlnVarType { 33 | public: 34 | PlnStructVarType(PlnTypeInfo* typeinf, const string &mode) : PlnVarType(typeinf, mode) {} 35 | ~PlnStructVarType() {}; 36 | 37 | string tname() override; 38 | PlnExpression *getAllocEx(vector &args) override; 39 | PlnExpression *getInternalAllocEx(PlnExpression* alloc_var, vector &args) override; 40 | PlnExpression *getFreeEx(PlnExpression* free_var) override; 41 | PlnExpression *getInternalFreeEx(PlnExpression* free_var, vector &args) override; 42 | PlnExpression* getCopyEx(PlnExpression* dst_var, PlnExpression* src_var, vector &args) override; 43 | }; 44 | -------------------------------------------------------------------------------- /idea/Array.pa: -------------------------------------------------------------------------------- 1 | int n=10; 2 | [10]int64 a; // 10の固定配列(要素数はコンパイラが管理/Cと同等) 3 | 4 | []int64 au = [1..10]; // 10の固定配列(要素数はコンパイラが管理/Cと同等) 5 | 6 | [#n]int64 b; // 未定要素数の固定配列(要素数は配列アドレスの一つ前に管理/Cに渡せる) 7 | [#10]int64 c; // あえて明示未定要素数の固定配列(要素数は配列アドレスの一つ前に管理) 8 | [+3]int64 aa; // 可変配列(メンバーとして要素アドレス, 要素数をもつ※要素アドレス不定のためCと互換性なし) 9 | 10 | [4,3]int64 m; // 3x4の固定配列 (メモリ上は [3][3][3][3]) 11 | // access : a[y,x] = a[y][x]; 12 | 13 | [#4,3]int64 mb; // 3x4の要素数未定固定配列 (メモリ上は #3#4[3][3][3][3]) 14 | // メンバーに一つでも#があれば要素数未定配列となる 15 | // int64[#y,x] != int64[#x][#y] 16 | // #x#y[x][x]... != #y[(#x[x]),(#x[x])... 17 | [+][+]int64 mm; // 可変配列の可変配列 18 | [4,3][+]int64 mmm; // 可変配列の固定長配列(メモリ上は[][]...) 19 | 20 | [3]@int64 ref; //整数の参照の配列 21 | @[3]int64 ref; //固定配列の参照 (int64->[3]->*) 22 | @[?]int64 cref; //要素数未管理配列への参照(Cのポインタ同等) (int64->[?]->*) 23 | [3]@[3]int64 ref; //固定配列の参照の配列 (int64->[3]->*->[3]) 24 | [4]@@[3]int64 ref; //固定配列の参照の参照の配列(参照の参照をゆるす?) 25 | [3]@[3]@int64 ref; //参照の配列の参照の配列 (int64->*->[3]->*->[3]) 26 | 27 | // 初期化例 28 | [,]int64 m1 = [1,2,3,4][5,6,7,8][9,10,11,12]; // no camma between dim. 29 | 30 | [3,4]int64 m2 = [1..12]; 31 | [#n,4]int64 m2a = [1..4*n]; 32 | 33 | [#3,4]int64 m3 = 0; // all 0; 34 | [+][+]int64 m4 = [[1,2,3,4],[3],[2,3,4]]; // need camma. 35 | 36 | // 代入パターン 37 | [3]int64 a3 = [1,2,3]; 38 | [5]int64 a5 = [9,9,9,9,9]; 39 | [3]int32 b3 = [1,2,3]; 40 | 41 | // ok 42 | [5,6,7] -> a5[2:]; // [9,9,5,6,7] 43 | a3 -> a5; // [1,2,3,6,7] 44 | 7->a5[2]; 45 | a5 -> a3; // [1,2,7] 46 | a3 -> a5[2:]; // [1,2,1,2,7] 47 | 48 | // NG? 49 | // b3->a3; // [1,2,3]? 50 | 51 | 52 | func setArray(=>[10]int64 a, [#]int64 b, [+]int64 aa, [3,4]int64m, [+][+]int64 mm) 53 | { 54 | } 55 | -------------------------------------------------------------------------------- /src/models/expressions/assignitem/PlnChainAssignItem.h: -------------------------------------------------------------------------------- 1 | /// Assignment Item class definition. 2 | /// 3 | /// @file PlnChainAssignItem.h 4 | /// @copyright 2018 YAMAGUCHI Toshinobu 5 | 6 | class PlnChainAssignItem : public PlnAssignItem 7 | { 8 | PlnExpression* src_ex; 9 | struct DstInf { 10 | PlnDstItem* item; 11 | }; 12 | vector dsts; 13 | 14 | public: 15 | PlnChainAssignItem(PlnExpression* ex) : src_ex(ex) { 16 | BOOST_ASSERT(src_ex->type == ET_ASSIGN); 17 | } 18 | 19 | ~PlnChainAssignItem() { 20 | for (auto di: dsts) 21 | delete di.item; 22 | } 23 | 24 | void addDstEx(PlnExpression* ex, bool need_save) override { 25 | BOOST_ASSERT(ex->values.size() == 1); 26 | auto v = ex->values[0]; 27 | 28 | BOOST_ASSERT(v.type == VL_VAR); 29 | dsts.push_back( {PlnDstItem::createDstItem(ex, need_save)} ); 30 | } 31 | 32 | int addDataPlace(vector &data_places, int start_ind) { 33 | for (auto &di: dsts) { 34 | di.item->place = data_places[start_ind]; 35 | start_ind++; 36 | if (start_ind >= data_places.size()) 37 | break; 38 | } 39 | return start_ind; 40 | } 41 | 42 | void finishS(PlnDataAllocator& da, PlnScopeInfo& si) override { 43 | for (auto &di: dsts) { 44 | PlnFinishRole fr = di.item->setSrcEx(da, si, src_ex); 45 | BOOST_ASSERT(fr == FINISH_BY_ASSIGNITEM); 46 | } 47 | 48 | src_ex->finish(da, si); 49 | } 50 | 51 | void finishD(PlnDataAllocator& da, PlnScopeInfo& si) override { 52 | for (auto &di: dsts) 53 | di.item->finish(da, si); 54 | } 55 | 56 | void genS(PlnGenerator& g) override { 57 | src_ex->gen(g); 58 | } 59 | 60 | void genD(PlnGenerator& g) override { 61 | for (auto di: dsts) 62 | di.item->gen(g); 63 | } 64 | }; 65 | 66 | -------------------------------------------------------------------------------- /src/models/expressions/assignitem/arrval_imp/PlnAssignArrayValue_Static.h: -------------------------------------------------------------------------------- 1 | /// Assignment Item class definition. 2 | /// 3 | /// @file PlnAssignArrayValue_Static.h 4 | /// @copyright 2021 YAMAGUCHI Toshinobu 5 | 6 | class PlnAssignArrayValue_Static : public PlnAssignItem { 7 | PlnArrayValue* src_ex; 8 | PlnExpression* dst_ex; 9 | PlnDstItem *dst_item; 10 | PlnDataPlace *output_place; 11 | 12 | public: 13 | PlnAssignArrayValue_Static(PlnExpression* ex) : dst_item(NULL), output_place(NULL), dst_ex(NULL) { 14 | BOOST_ASSERT(ex->type = ET_ARRAYVALUE); 15 | src_ex = static_cast(ex); 16 | } 17 | 18 | ~PlnAssignArrayValue_Static() { 19 | delete dst_item; 20 | } 21 | 22 | void addDstEx(PlnExpression* ex, bool need_save) override { 23 | BOOST_ASSERT(ex->values[0].type == VL_VAR); 24 | BOOST_ASSERT(ex->values[0].getVarType()->data_type() == DT_OBJECT_REF 25 | || ex->values[0].getVarType()->data_type() == DT_OBJECT); 26 | BOOST_ASSERT(!need_save); 27 | 28 | dst_ex = ex; 29 | } 30 | 31 | int addDataPlace(vector &data_places, int start_ind) override { 32 | output_place = data_places[start_ind]; 33 | return start_ind + 1; 34 | } 35 | 36 | void finishS(PlnDataAllocator& da, PlnScopeInfo& si) override { 37 | BOOST_ASSERT(dst_ex->values[0].asgn_type != ASGN_MOVE); 38 | 39 | dst_item = PlnDstItem::createDstItem(dst_ex, false); 40 | dst_item->place = output_place; 41 | dst_item->setSrcEx(da, si, src_ex); 42 | src_ex->finish(da, si); 43 | } 44 | 45 | void finishD(PlnDataAllocator& da, PlnScopeInfo& si) override { 46 | dst_item->finish(da,si); 47 | } 48 | 49 | void genS(PlnGenerator& g) override { 50 | src_ex->gen(g); 51 | } 52 | 53 | void genD(PlnGenerator& g) override { 54 | dst_item->gen(g); 55 | } 56 | }; 57 | 58 | -------------------------------------------------------------------------------- /idea/CCall.pa: -------------------------------------------------------------------------------- 1 | type FILE; 2 | ccall printf(@[?]byte format, ...) -> int32; 3 | ccall sprintf(@, @[?]byte format, ... => [?]byte str) -> int32; 4 | ccall scanf(@[?]byte format => ...) -> int32; 5 | ccall sscanf(@[?]byte str, @[?]byte format => ...) -> int32; 6 | ccall strcpy([?]byte >>dst, @[?]byte src) -> [?]byte; 7 | 8 | ccall fopen(@[?]byte filename, mode) -> FILE; 9 | ccall fclose(FILE >>stream) -> int32; 10 | ccall int32 sqlite3_open([?]byte filename => sqlite3 db>>); 11 | 12 | [80]byte str; 13 | int32 result; 14 | "Hello Horld" -> sprintf(=>str) -> result; 15 | 16 | str ->> strcpy("TEST") ->> str; 17 | str.strcpy("TEST"); 18 | 19 | flo64 d; 20 | int32 i; 21 | "1.23 5", "%f %d" -> sscanf(=> d, i) -> result; 22 | 23 | if (("1.23 5" -> sscanf("%f %d" => d, i)) == 0) { 24 | printf("err\n"); 25 | } 26 | 27 | FILE f <<= fopen("aa.txt","r"); 28 | f ->> fclose(); 29 | 30 | // if constructor = fopen. which is good? 31 | FILE f = {"aa.txt", "r"}; 32 | FILE f = ("aa.txt", "r"); 33 | FILE f = {filename: "aa.txt", mode: "r"}; 34 | FILE f("aa.txt", "r"); 35 | 36 | // idea of param C -> pa 37 | char *p, char p[]: 38 | clone: [?]byte pa "wmh"+"wis" 39 | move: caller [?]byte pa>> : callee [?]byte >>pa "wmh"+"wis" 40 | after => 41 | write(io): [?]byte pa "wmr"+"wis" 42 | 43 | const char *p: 44 | readonly: @[?]byte p "rir"+"ris" 45 | readonly: @byte p "rir" 46 | 47 | char **p: 48 | after => 49 | write: @![?]byte p "wcr"+"wis" 50 | write: @!byte p "wcr"+"wis" 51 | move: caller [?]byte >>pa : callee [?]byte pa>> "wmh"+"wis" 52 | 53 | complex case: 54 | clone: [?]@[?]byte p "wmh" 55 | readonly?: @[?]@![?]byte p "rir"+"wcr"+"wis" 56 | move: 57 | after => 58 | write: [?]@![?]byte p "wmh"+"wcr"+"wis" 59 | write: @![?]@[?]byte p "wcr"+"rir"+"ris" 60 | write: @![?]@![?]byte p "wcr"+"wcr"+"wis" 61 | 62 | -------------------------------------------------------------------------------- /src/test/pacode/030_reference.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | ccall setenv(...); 3 | ccall mtrace(); 4 | ccall muntrace(); 5 | 6 | setenv("MALLOC_TRACE", "out/mtrace030-1", 1); 7 | 8 | int32 i1,i2,i3,i4,i5,i6; 9 | byte b1,b2,b3,b4; 10 | 11 | mtrace(); 12 | { 13 | @[3]int32 arr1 = [1,2,3]; 14 | arr1[1] -> i1; 15 | 16 | [2]@[3]int32 arr2 = [1,2,3][4,5,6]; 17 | arr2[1][1] -> i2; 18 | 19 | [3]int32 arr3 = arr1; 20 | arr3[2] -> i3; 21 | 22 | [2][3]int32 aaa = arr2; 23 | 24 | [1][2]@[3]int32 x1 = [[1,2,3][4,5,6]]; 25 | [1][2][3]int32 x2 = x1; 26 | x2[0][1][1] -> i4; 27 | 9 -> x2[0][0][1]; // check writable. 28 | 29 | @[3]int32 xx = x2[0][0]; 30 | xx[1] -> i5; 31 | refread(x1[0][1], 1) -> i6; 32 | 33 | @[10]byte str = "test"; 34 | [2]@[10]byte strs = ["test1", "test2"]; 35 | [2]@[?]byte strs2 = ["test3", "test4"]; 36 | []@[?]byte strs3 = ["test1", "test4"]; 37 | 38 | str[2] -> b1; 39 | strs[1][4] -> b2; 40 | strs2[0][4] -> b3; 41 | strs3[1][4] -> b4; 42 | } 43 | muntrace(); 44 | 45 | printf("%d %d %d %d %d %d %c%c%c%c\n", i1, i2, i3, i4, i5, i6, b1,b2,b3,b4); 46 | 47 | type A { 48 | int16 i; 49 | @[3]int32 arr; 50 | }; 51 | 52 | type B { 53 | byte b1; 54 | byte b2; 55 | flo64 d; 56 | flo32 f; 57 | }; 58 | 59 | flo64 d, flo32 f; 60 | 61 | setenv("MALLOC_TRACE", "out/mtrace030-2", 1); 62 | mtrace(); 63 | { 64 | A a = [3, [1,2,3]]; 65 | @A b = a; 66 | @[3]int32 aarr = b.arr; 67 | aarr[1] -> i1; 68 | 69 | @B bb = [1,2,1.23,2.34]; 70 | bb.b2 -> b2; 71 | bb.d -> d; 72 | bb.f -> f; 73 | 74 | calcB(createB()!); 75 | } 76 | muntrace(); 77 | 78 | printf("%d %d %.2f %.2f", i1, b2, d, f); 79 | 80 | func refread(@[3]int32 arr, int32 x) -> int32 i 81 | { 82 | arr[x] -> i; 83 | } 84 | 85 | func createB() -> B b 86 | { 87 | 2->b.b1; 88 | } 89 | 90 | func calcB(@!B b) 91 | { 92 | 1->b.b1; 93 | } 94 | 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Palan 2 | [![build](https://github.com/tosyama/palan/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/tosyama/palan/actions/workflows/build.yml) 3 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/8224c75046a04172a3798c29dd3aedd0)](https://www.codacy.com/app/tosyama/palan?utm_source=github.com&utm_medium=referral&utm_content=tosyama/palan&utm_campaign=Badge_Grade) 4 | [![Coverage Status](https://img.shields.io/coveralls/github/tosyama/palan/master.svg)](https://coveralls.io/github/tosyama/palan?branch=master) 5 | Palan is aiming simpler, safer and more enjoyable programming language alternative C. 6 | Current palan is very draft. 7 | 8 | ## Quick Start 9 | ### Environment 10 | * Ubuntu 18.04.1 LTS or later 11 | * g++ gcc 7.3.0 or later 12 | * GNU Make 13 | * curl 14 | * git 15 | 16 | ### Build Palan Compiler 17 | ```console 18 | $ git clone --recursive https://github.com/tosyama/palan.git 19 | $ cd palan 20 | $ sudo make package 21 | $ make 22 | ``` 23 | Note: `make package` installs [Boost][boost], [Bison][bison], [Flex][flex] and [Catch][catch]. You might need to install libncursesw5-dev. 24 | 25 | ### Write Code 26 | ```console 27 | $ vi helloworld.pa 28 | ``` 29 | ```go 30 | ccall printf(...); 31 | "Hello World!\n" -> printf(); 32 | ``` 33 | 34 | ### Build and Run 35 | ```console 36 | $ bin/pac helloworld.pa -o a.out 37 | $ ./a.out 38 | Hello World! 39 | ``` 40 | 41 | ## Reference 42 | See [Palan Language Reference](https://github.com/tosyama/palan/tree/master/doc/REFERENCE.md). 43 | See qiita for Japanese edition [Palan 0.3 Language Reference(JP)](https://qiita.com/tosyama/items/44146bb978a31679e177). 44 | 45 | [boost]: http://boost.org 46 | [bison]: https://www.gnu.org/software/bison/ 47 | [flex]: https://github.com/westes/flex 48 | [catch]: https://github.com/philsquared/Catch 49 | -------------------------------------------------------------------------------- /src/test/coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Coverage check tool 3 | 4 | # target="../generators/PlnX86_64Generator" 5 | # target="../generators/PlnX86_64DataAllocator" 6 | # target="../generators/PlnX86_64RegisterMachine" 7 | # target="../generators/PlnX86_64RegisterSave" 8 | # target="../generators/PlnX86_64CalcOptimization" 9 | # target="../PlnDataAllocator" 10 | # target="../models/PlnObjectLiteral" 11 | # target="../models/PlnBlock" 12 | # target="../models/PlnModule" 13 | # target="../models/PlnType" 14 | # target="../models/PlnFunction" 15 | # target="../PlnMessage" 16 | #target="../PlnModelTreeBuilder" 17 | # target="../PlnGenerator" 18 | # target="../models/PlnExpression" 19 | # target="../models/expressions/PlnMulOperation" 20 | # target="../models/expressions/PlnArrayValue" 21 | # target="../models/expressions/PlnFunctionCall" 22 | # target="../models/expressions/PlnBoolExpression" 23 | # target="../models/expressions/PlnBoolOperation" 24 | # target="../models/expressions/PlnCmpOperation" 25 | # target="../models/expressions/PlnReferenceValue" 26 | # target="../models/types/PlnArrayValueType" 27 | # target="../models/types/PlnFixedArrayType" 28 | # target="../models/types/PlnStructType" 29 | target="../models/expressions/assignitem/PlnAssignItem" 30 | targetnm=${target##*/} 31 | gcovs="${targetnm}.cpp" 32 | #gcovs="PlnAssignArrayValue.h" 33 | #gcovs="PlnArrayValueType.h" 34 | #gcovs="PlnStructType.h" 35 | #gcovs="PlnDstCopyObjectItem.h" 36 | gcovs="PlnAssignWorkValsItem.h" 37 | #gcovs="PlnAssignArrayValue_IndirectVar.h" 38 | #gcovs="PlnFixedArrayType.h" 39 | # gcovs="PlnDstMoveObjectItem.h" 40 | 41 | g++ -coverage -std=c++11 -c -g ${target}.cpp -o ../objs/${targetnm}.o 42 | make LDFLAGS=-coverage -lgcov 43 | ./tester 44 | gcov ../objs/${targetnm}.gcda | grep -A 1 -E ${gcovs} 45 | 46 | rm ../objs/${targetnm}.* 47 | rm $(ls ./*.gcov | grep -E -v ${gcovs}) 48 | 49 | -------------------------------------------------------------------------------- /src/generators/PlnX86_64DataAllocator.h: -------------------------------------------------------------------------------- 1 | /// x86-64 (Linux) data allocation management class declaration. 2 | /// 3 | /// @file PlnX86_64DataAllocator.h 4 | /// @copyright 2017-2020 YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnDataAllocator.h" 7 | 8 | enum { 9 | RAX, RBX, RCX, RDX, 10 | RDI, RSI, RBP, RSP, 11 | R8, R9, R10, R11, 12 | R12, R13, R14, R15, 13 | XMM0, XMM1, XMM2, XMM3, 14 | XMM4, XMM5, XMM6, XMM7, 15 | XMM8, XMM9, XMM10, XMM11, 16 | XMM12, XMM13, XMM14, XMM15, 17 | RIP, REG_NUM, 18 | }; 19 | 20 | enum { // for custom_inf 21 | IS_RETVAL = 1 22 | }; 23 | 24 | class PlnX86_64DataAllocator: public PlnDataAllocator 25 | { 26 | void destroyRegsByFuncCall(); 27 | bool tryMoveDp2Reg(PlnDataPlace* dp, int regid); 28 | 29 | protected: 30 | void setArgDps(int func_type, vector &arg_dps, bool is_callee); 31 | void setRetValDps(int func_type, vector &retval_dps, bool is_callee); 32 | 33 | public: 34 | PlnX86_64DataAllocator(); 35 | 36 | void funcCalled(vector& args, int func_type, bool never_return) override; 37 | 38 | void prepareMemCopyDps(PlnDataPlace* &dst, PlnDataPlace* &src, PlnDataPlace* &len) override; 39 | void memCopyed(PlnDataPlace* dst, PlnDataPlace* src, PlnDataPlace* len) override; 40 | 41 | PlnDataPlace* prepareAccumulator(int data_type, int data_size) override; 42 | PlnDataPlace* added(PlnDataPlace* ldp, PlnDataPlace *rdp) override; 43 | PlnDataPlace* multiplied(PlnDataPlace* ldp, PlnDataPlace* rdp) override; 44 | PlnDataPlace* divided(PlnDataPlace* ldp, PlnDataPlace* rdp, bool is_mod) override; 45 | 46 | // for array item 47 | PlnDataPlace* prepareObjBasePtr() override; 48 | PlnDataPlace* prepareObjIndexPtr() override; 49 | PlnDataPlace* prepareObjIndexPtr(int staticIndex) override; 50 | 51 | // for optimization 52 | void optimizeRegAlloc() override; 53 | 54 | // for debug 55 | void checkDataLeak() override; 56 | }; 57 | 58 | -------------------------------------------------------------------------------- /src/test/pacode/006_intarray.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | ccall setenv(...); 3 | ccall mtrace(); 4 | ccall muntrace(); 5 | 6 | [3]int16 o, o2; 7 | [1]int16 o3; 8 | setenv("MALLOC_TRACE", "out/mtrace006", 1); 9 | mtrace(); 10 | { 11 | // alloc only 12 | [10]int32 a; 13 | [3]int16 b, c; 14 | 15 | // d: copy of a, e: use return as is. 16 | [10]int32 d = a; 17 | [3]int16 e = arr_func(1, a); 18 | [3]int16 f <<= e; 19 | int32 xx = 10; 20 | 21 | arr_func(3, a) -> b; 22 | arr_func(4, a>>) ->> b, xx; 23 | xx -> o3[0]; 24 | 25 | int16 ind = 1; 26 | 27 | 5 -> b[ind-1]; // b[0]=5 28 | 2 -> b[ind]; // b[1]=2 29 | 30 | int32_func(b[1],b[0]-1) -> b[0], b[2u]; // b[0]=3, b[2]=4 31 | 32 | int16 s = b[0] + 1; // s=4 33 | 34 | b ->> c; // b=undefined, c[0]=3,c[1]=2,c[2]=4 35 | c -> o; 36 | s -> o[2]; 37 | 38 | int32_func2(c[0],c[1]) -> o2[0]; // o2[0] = 5 39 | 40 | s + o2[s * 0] -> o2[c[0]-2]; // o2[1] = 9 41 | 42 | [3,5]int16 a2, b2; 43 | [3,4,2]int16 a3; 44 | 45 | 1->s; 46 | 1->a2[0,0]; 47 | 2->a2[s,0]; 48 | 3->a2[2,3]; 49 | 4->a2[2,s]; 50 | 5->a2[0,s]; 51 | 6->a2[s,s]; 52 | 53 | a2 -> b2; 54 | // a2[1,0]:2+1 -> a3[1+1:2,3,b2[0,0]:1] = 3 55 | a2[s,0]+s -> a3[s+1,3,b2[0,s-1]]; 56 | a3[2,3,1] -> o2[2]; 57 | 58 | // not treat returned array. 59 | [10]int32 a4; 60 | 61 | arr_func(1, a4); 62 | arr_func(1, a4>>); 63 | 64 | } 65 | muntrace(); 66 | 67 | printf("%d %d %d %d %d %d %d\n", o[0], o[1], o[2], o2[0], o2[1], o2[2], o3[0]); 68 | 69 | func arr_func(int32 x, [10]int32 pa) 70 | -> [3]int16 pb 71 | { 72 | [5]int32 a1; 73 | { 74 | [5]int16 a2; 75 | [3]int16 a3; 76 | return a3 77 | } 78 | [10]byte a4; 79 | return 80 | } 81 | 82 | func arr_func(int32 x, [10]int32>> pa) 83 | -> [3]int16 pb, int32 x 84 | { 85 | [5]int32 a1; 86 | 10 -> pa[9]; 87 | } 88 | 89 | func int32_func(int32 i, j) 90 | -> int32 x, y 91 | { 92 | i+1,j -> x, y 93 | } 94 | 95 | func int32_func2(int32 i, j) -> int32 96 | { 97 | return i+j 98 | } 99 | -------------------------------------------------------------------------------- /src/models/types/PlnFixedArrayType.h: -------------------------------------------------------------------------------- 1 | /// Fixed array type class declaration. 2 | /// 3 | /// @file PlnFixedArrayType.h 4 | /// @copyright 2019-2022 YAMAGUCHI Toshinobu 5 | 6 | class PlnFixedArrayTypeInfo : public PlnTypeInfo { 7 | public: 8 | PlnVarType* item_type; 9 | bool has_heap_member; 10 | PlnFunction* alloc_func; 11 | PlnFunction* internal_alloc_func; 12 | PlnFunction* free_func; 13 | PlnFunction* internal_free_func; 14 | PlnFunction* copy_func; 15 | 16 | PlnFixedArrayTypeInfo(string &name, PlnVarType* item_type, PlnBlock* parent); 17 | PlnTypeConvCap canCopyFrom(const string& mode, PlnVarType *src, PlnAsgnType copymode) override; 18 | 19 | PlnVarType* getVarType(const string& mode) override; 20 | PlnVarType* getVarType(const string& mode, vector init_args); 21 | }; 22 | 23 | class PlnFixedArrayVarType : public PlnVarType { 24 | public: 25 | vector sizes; 26 | PlnFixedArrayVarType(PlnTypeInfo* typeinf, const string &mode) : PlnVarType(typeinf, mode) { } 27 | ~PlnFixedArrayVarType() {}; 28 | 29 | string tname() override; 30 | int size() override; 31 | PlnVarType* getVarType(const string& mode) override; 32 | PlnTypeConvCap canCopyFrom(PlnVarType *src, PlnAsgnType copymode) override; 33 | 34 | PlnVarType* item_type() { 35 | auto farr_type = dynamic_cast(typeinf); 36 | BOOST_ASSERT(farr_type); 37 | return farr_type->item_type; 38 | 39 | } 40 | 41 | void getAllocArgs(vector &alloc_exps) override; 42 | PlnExpression* getAllocEx(vector &args) override; 43 | PlnExpression* getInternalAllocEx(PlnExpression* alloc_var, vector &args) override; 44 | PlnExpression* getFreeEx(PlnExpression* free_var) override; 45 | PlnExpression* getInternalFreeEx(PlnExpression* free_var, vector &args) override; 46 | PlnExpression* getCopyEx(PlnExpression* dst_var, PlnExpression* src_var, vector &args) override; 47 | }; 48 | -------------------------------------------------------------------------------- /src/models/expressions/PlnFunctionCall.h: -------------------------------------------------------------------------------- 1 | /// PlnFunctionCall model class declaration. 2 | /// 3 | /// @file PlnFunctionCall.h 4 | /// @copyright 2017-2022 YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnExpression.h" 7 | 8 | enum PlnInternalFuncType { 9 | IFUNC_MALLOC, 10 | IFUNC_FREE, 11 | IFUNC_EXIT, 12 | IFUNC_NUM 13 | }; 14 | 15 | enum PlnArgOption { 16 | AG_NONE = 0, 17 | AG_MOVE, 18 | AG_WREF 19 | }; 20 | 21 | class PlnClone; 22 | 23 | class PlnArgValueInf { 24 | public: 25 | PlnParameter* param; 26 | int iomode; 27 | PlnArgOption opt; 28 | int va_idx; // not variable argument(va): -1, va: >=0 29 | PlnArgValueInf(PlnParameter* param, int iomode) 30 | : param(param), iomode(iomode), opt(AG_NONE), va_idx(-1) {} 31 | PlnArgValueInf(int iomode) 32 | : param(NULL), iomode(iomode), opt(AG_NONE), va_idx(-1) {} 33 | }; 34 | 35 | class PlnArgument { 36 | public: 37 | PlnExpression* exp; 38 | vector inf; 39 | PlnArgument(PlnExpression* exp) : exp(exp) { } 40 | PlnArgument(PlnExpression* exp, int iomode) : exp(exp) { 41 | int size = exp ? exp->values.size() : 1; 42 | for (int i; i arguments; 55 | vector arg_dps; 56 | vector ret_dps; 57 | vector free_work_vars; 58 | vector free_vars; 59 | vector free_exs; 60 | vector clones; 61 | 62 | PlnFunctionCall(PlnFunction* f); 63 | PlnFunctionCall(PlnFunction* f, vector &args); 64 | PlnFunctionCall(PlnFunction* f, vector &args); 65 | ~PlnFunctionCall(); 66 | 67 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override; 68 | void gen(PlnGenerator& g) override; 69 | 70 | static PlnFunction* getInternalFunc(PlnInternalFuncType func_type); 71 | }; 72 | 73 | -------------------------------------------------------------------------------- /src/models/expressions/PlnCalcOperationUtils.h: -------------------------------------------------------------------------------- 1 | /// Calculate operation utilities. 2 | /// 3 | /// @file PlnCalcOperationUtls.h 4 | /// @copyright 2021 YAMAGUCHI Toshinobu 5 | 6 | #define CREATE_CHECK_FLAG(ex) bool is_##ex##_int = false, is_##ex##_uint = false, is_##ex##_flo = false; \ 7 | union {int64_t i; uint64_t u; double d;} ex##val; \ 8 | if (ex->type == ET_VALUE) { \ 9 | switch (ex->values[0].type) { \ 10 | case VL_LIT_INT8: is_##ex##_int = true; \ 11 | ex##val.i = ex->values[0].inf.intValue; break;\ 12 | case VL_LIT_UINT8: is_##ex##_uint = true; \ 13 | ex##val.u = ex->values[0].inf.uintValue; break; \ 14 | case VL_LIT_FLO8: is_##ex##_flo = true; \ 15 | ex##val.d = ex->values[0].inf.floValue; break; \ 16 | } \ 17 | } \ 18 | bool is_##ex##_num_lit = is_##ex##_int || is_##ex##_uint || is_##ex##_flo; 19 | 20 | inline PlnVarType* binaryOperationType(PlnExpression* l, PlnExpression* r) 21 | { 22 | int ldtype = l->getDataType(); 23 | int rdtype = r->getDataType(); 24 | bool isUnsigned = (ldtype == DT_UINT && rdtype == DT_UINT); 25 | bool isFloat = (ldtype == DT_FLOAT || rdtype == DT_FLOAT); 26 | 27 | if (isFloat) { 28 | int fsize = 0; 29 | if (ldtype == DT_FLOAT && rdtype != DT_FLOAT) { 30 | fsize = l->values[0].getVarType()->size(); 31 | } else if (ldtype != DT_FLOAT && rdtype == DT_FLOAT) { 32 | fsize = r->values[0].getVarType()->size(); 33 | } else if (l->values[0].type == VL_LIT_FLO8) { 34 | fsize = r->values[0].getVarType()->size(); 35 | } else if (r->values[0].type == VL_LIT_FLO8) { 36 | fsize = l->values[0].getVarType()->size(); 37 | } else { 38 | fsize = std::max( 39 | l->values[0].getVarType()->size(), 40 | r->values[0].getVarType()->size()); 41 | } 42 | 43 | if (fsize == 8) { 44 | return PlnVarType::getFlo64(); 45 | } else if (fsize == 4) { 46 | return PlnVarType::getFlo32(); 47 | } else 48 | BOOST_ASSERT(false); 49 | 50 | } else if (isUnsigned) { 51 | return PlnVarType::getUint(); 52 | } 53 | 54 | return PlnVarType::getSint(); 55 | } 56 | -------------------------------------------------------------------------------- /tools/pa.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: Palan 3 | " Maintainer: Toshinobu YAMAGUCHI 4 | " Last Change: 2021 Jun 23 5 | 6 | if exists('b:current_syntax') 7 | finish 8 | endif 9 | 10 | syn keyword paDeclaration type var const func syscall ccall 11 | syn keyword paConditional if else 12 | syn keyword paRepeat while 13 | syn keyword paStatement return break continue extern 14 | syn match paOperator "[.,?!*+/%&\-<>=@\|#]" 15 | syn match paOperator "[][()]" 16 | syn match paDelimiter "[{};]" 17 | 18 | hi def link paConditional Conditional 19 | hi def link paDeclaration Keyword 20 | hi def link paRepeat Repeat 21 | hi def link paStatement Statement 22 | hi def link paOperator Operator 23 | hi def link paDelimiter Delimiter 24 | 25 | syn keyword paSIntType sbyte int16 int32 int64 26 | syn keyword paUIntType byte uint16 uint32 uint64 27 | syn keyword paFloType flo32 flo64 28 | 29 | hi def link paSIntType Type 30 | hi def link paUIntType Type 31 | hi def link paFloType Type 32 | 33 | syn region paComment start="//" end="$" contains=@Spell 34 | hi def link paComment Comment 35 | 36 | " String 37 | syn region paString start=+"+ skip=+\\\\\|\\"+ end=+"+ 38 | hi def link paString String 39 | 40 | " Regions 41 | syn region paBlock start="{" end="}" transparent fold 42 | syn region paParen start='(' end=')' transparent 43 | 44 | " Integers 45 | syn match paDecimalInt "\<\d\+\([Ee]\d\+\)\?\>" 46 | syn match paHexadecimalInt "0x\x\+\(u\=l\{0,2}\|ll\=u\)\>" 47 | hi def link paDecimalInt Number 48 | hi def link paHexadecimalInt Number 49 | 50 | " Floating point 51 | syn match paImaginary "\<\d\+\.\d*\([Ee][-+]\d\+\)\?i\>" 52 | hi def link paImaginary Number 53 | 54 | let b:current_syntax = 'pa' 55 | -------------------------------------------------------------------------------- /src/models/expressions/PlnMemCopy.h: -------------------------------------------------------------------------------- 1 | /// PlnMemCopy Expression model class declaration. 2 | /// 3 | /// @file PlnMemCopy.h 4 | /// @copyright 2018-2022 YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnExpression.h" 7 | 8 | class PlnMemCopy : public PlnExpression { 9 | public: 10 | PlnExpression *dst_ex, *src_ex, *len_ex; 11 | PlnDataPlace *cp_dst_dp, *cp_src_dp, *cp_len_dp; 12 | int cp_unit; 13 | PlnMemCopy(PlnExpression *dst, PlnExpression *src, PlnExpression *len) 14 | : dst_ex(dst), src_ex(src), len_ex(len), cp_dst_dp(NULL), cp_src_dp(NULL), cp_len_dp(NULL), 15 | cp_unit(1), PlnExpression(ET_MCOPY) 16 | { 17 | BOOST_ASSERT(dst && src && len); 18 | BOOST_ASSERT(len_ex->type == ET_VALUE); 19 | BOOST_ASSERT(len_ex->values[0].type == VL_LIT_UINT8); 20 | 21 | uint64_t cp_size = len_ex->values[0].inf.uintValue; 22 | if ((cp_size % 8) == 0) { 23 | cp_size /= 8; cp_unit = 8; 24 | } else if ((cp_size % 4) == 0) { 25 | cp_size /= 4; cp_unit = 4; 26 | } else if ((cp_size % 2) == 0) { 27 | cp_size /= 2; cp_unit = 2; 28 | } 29 | len_ex->values[0].inf.uintValue = cp_size; 30 | } 31 | 32 | ~PlnMemCopy() { 33 | delete src_ex; 34 | delete dst_ex; 35 | delete len_ex; 36 | } 37 | 38 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override { 39 | da.prepareMemCopyDps(cp_dst_dp, cp_src_dp, cp_len_dp); 40 | 41 | src_ex->data_places.push_back(cp_src_dp); 42 | src_ex->finish(da, si); 43 | 44 | dst_ex->data_places.push_back(cp_dst_dp); 45 | dst_ex->finish(da, si); 46 | 47 | len_ex->data_places.push_back(cp_len_dp); 48 | len_ex->finish(da, si); 49 | 50 | da.popSrc(cp_src_dp); 51 | da.popSrc(cp_dst_dp); 52 | da.popSrc(cp_len_dp); 53 | da.memCopyed(cp_dst_dp, cp_src_dp, cp_len_dp); 54 | } 55 | 56 | void gen(PlnGenerator& g) override { 57 | src_ex->gen(g); 58 | dst_ex->gen(g); 59 | len_ex->gen(g); 60 | 61 | g.genLoadDp(cp_src_dp); 62 | g.genLoadDp(cp_dst_dp); 63 | g.genLoadDp(cp_len_dp); 64 | 65 | static string cmt = "deep copy"; 66 | g.genMemCopy(cp_unit, cmt); 67 | } 68 | }; 69 | -------------------------------------------------------------------------------- /src/models/PlnConditionalBranch.cpp: -------------------------------------------------------------------------------- 1 | /// Conditinal branch model classes definition. 2 | /// 3 | /// @file PlnConditionalBranch.cpp 4 | /// @copyright 2018-2022 YAMAGUCHI Toshinobu 5 | 6 | #include "boost/assert.hpp" 7 | #include "../PlnConstants.h" 8 | #include "PlnConditionalBranch.h" 9 | #include "PlnModule.h" 10 | #include "PlnBlock.h" 11 | #include "../PlnScopeStack.h" 12 | #include "../PlnGenerator.h" 13 | #include "expressions/PlnCmpOperation.h" 14 | 15 | PlnIfStatement::PlnIfStatement 16 | (PlnExpression* condition, PlnBlock* block, PlnStatement* next, PlnBlock* parent) 17 | : cond_dp(NULL), jmp_next_id(-1), jmp_end_id(-1), next(next) 18 | { 19 | type = ST_IF; 20 | inf.block = block; 21 | block->setParent(parent); 22 | this->parent = parent; 23 | 24 | this->condition = PlnBoolExpression::create(condition); 25 | } 26 | 27 | PlnIfStatement::~PlnIfStatement() 28 | { 29 | delete condition; 30 | delete inf.block; 31 | if (next) 32 | delete next; 33 | } 34 | 35 | void PlnIfStatement::finish(PlnDataAllocator& da, PlnScopeInfo& si) 36 | { 37 | BOOST_ASSERT(si.scope[0].type == SC_MODULE); 38 | PlnModule* m = si.scope[0].inf.module; 39 | 40 | jmp_next_id = m->getJumpID(); 41 | 42 | condition->jmp_if = 0; 43 | condition->jmp_id = jmp_next_id; 44 | condition->finish(da, si); 45 | inf.block->finish(da, si); 46 | 47 | if (next) { 48 | next->finish(da, si); 49 | if (next->type == ST_IF) { 50 | jmp_end_id = static_cast(next)->jmp_end_id; 51 | } else { 52 | jmp_end_id = m->getJumpID(); 53 | } 54 | 55 | } else { 56 | jmp_end_id = jmp_next_id; 57 | } 58 | 59 | } 60 | 61 | void PlnIfStatement::gen(PlnGenerator& g) 62 | { 63 | condition->gen(g); 64 | inf.block->gen(g); 65 | 66 | if (next) { 67 | g.genJump(jmp_end_id, "end if"); 68 | g.genJumpLabel(jmp_next_id, "else"); 69 | next->gen(g); 70 | if (next->type != ST_IF) // else statement. 71 | g.genJumpLabel(jmp_end_id, "end else"); 72 | 73 | } else { // No additional else statement. 74 | g.genJumpLabel(jmp_next_id, "end if"); 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /src/models/PlnExpression.h: -------------------------------------------------------------------------------- 1 | /// Expression model class declaration. 2 | /// 3 | /// @file PlnExpression.h 4 | /// @copyright 2017-2020 YAMAGUCHI Toshinobu 5 | 6 | #pragma once 7 | #include "../PlnModel.h" 8 | 9 | // Expression: 10 | enum PlnExprsnType { 11 | ET_VALUE, 12 | ET_ARRAYVALUE, 13 | ET_FUNCCALL, 14 | ET_ADD, 15 | ET_MUL, 16 | ET_DIV, 17 | ET_NEG, 18 | ET_CMP, 19 | ET_AND, 20 | ET_OR, 21 | ET_ASSIGN, 22 | ET_CHAINCALL, 23 | ET_CLONE, 24 | ET_ARRAYITEM, 25 | ET_STRUCTMEMBER, 26 | ET_REFVALUE, 27 | ET_MCOPY, 28 | ET_TRUE, 29 | ET_FALSE, 30 | ET_VOID 31 | }; 32 | 33 | class PlnModule; 34 | class PlnExpression { 35 | public: 36 | PlnExprsnType type; 37 | vector data_places; 38 | vector values; 39 | string comment; 40 | PlnLoc loc; 41 | 42 | PlnExpression(PlnExprsnType type) : type(type) {}; 43 | PlnExpression(PlnValue value); 44 | virtual ~PlnExpression(); 45 | 46 | int getDataType(int val_ind=0); 47 | 48 | virtual PlnExpression* adjustTypes(const vector &types); 49 | virtual void finish(PlnDataAllocator& da, PlnScopeInfo& si); 50 | virtual void gen(PlnGenerator& g); 51 | }; 52 | 53 | // Value (rval) 54 | enum PlnValType { 55 | VL_UNKNOWN, 56 | VL_LIT_INT8, 57 | VL_LIT_UINT8, 58 | VL_LIT_FLO8, 59 | VL_LIT_STR, 60 | VL_LIT_ARRAY, 61 | VL_VAR, 62 | VL_WORK 63 | }; 64 | 65 | class PlnArrayValue; 66 | class PlnValue { 67 | public: 68 | PlnValType type; 69 | PlnAsgnType asgn_type; 70 | union { 71 | int index; 72 | int64_t intValue; 73 | uint64_t uintValue; 74 | double floValue; 75 | string *strValue; 76 | PlnArrayValue *arrValue; 77 | PlnVariable *var; 78 | PlnVarType *wk_type; 79 | } inf; 80 | 81 | PlnValue() : type(VL_UNKNOWN), asgn_type(NO_ASGN) {}; 82 | PlnValue(const PlnValue &src); 83 | PlnValue(int64_t intValue); 84 | PlnValue(uint64_t uintValue); 85 | PlnValue(double floValue); 86 | PlnValue(string strValue); 87 | PlnValue(PlnArrayValue *arr); 88 | PlnValue(PlnVariable* var); 89 | ~PlnValue(); 90 | 91 | PlnVarType* getVarType(); 92 | PlnDataPlace* getDataPlace(PlnDataAllocator& da); 93 | }; 94 | -------------------------------------------------------------------------------- /src/test/pacode/010_arrarray.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | ccall setenv(...); 3 | ccall mtrace(); 4 | ccall muntrace(); 5 | ccall exit(int32 x); 6 | 7 | func set_arrarr([3][4]int32 >>a) -> [3][4]int32 a 8 | { 9 | int32 i, j; 10 | 11 | 0 -> i; 12 | while i<3 { 13 | 0 -> j; 14 | while j<4 { 15 | i*4+j -> a[i][j]; 16 | j+1 -> j; 17 | } 18 | i+1 -> i; 19 | } 20 | } 21 | 22 | func inc_arrarr([3][4]int32 a) -> [3][4]int32 b 23 | { 24 | int32 i, j; 25 | 26 | 0 -> i; 27 | while i<3 { 28 | 0 -> j; 29 | while j<4 { 30 | a[i][j]+1 -> b[i][j]; 31 | j+1 -> j; 32 | } 33 | i+1 -> i; 34 | } 35 | } 36 | 37 | func set_arrarr2([4][2,3][5]int32 >>a) -> [4][2,3][5]int32 a 38 | { 39 | int32 i, j, k, l; 40 | 41 | 0 -> i; 42 | while i<4 { 43 | 0 -> j; 44 | while j<2 { 45 | 0 -> k; 46 | while k<3 { 47 | 0 -> l; 48 | while l<5 { 49 | i*1000+j*100+k*10+l -> a[i][j,k][l]; 50 | l+1 -> l; 51 | } 52 | k+1 -> k; 53 | } 54 | j+1 -> j; 55 | } 56 | i+1 -> i; 57 | } 58 | } 59 | 60 | [9]int32 o; 61 | 62 | setenv("MALLOC_TRACE", "out/mtrace010", 1); 63 | mtrace(); 64 | { 65 | [3][4]int32 a1; 66 | set_arrarr(a1>>) ->> a1; 67 | 68 | [3][4]int32 a2 = inc_arrarr(a1); 69 | [3][4]int32 a3 <<= inc_arrarr(a2); 70 | 71 | a1[2][3] -> o[0]; 72 | a2[2][3] -> o[1]; 73 | a3[2][3] -> o[2]; 74 | 75 | [4][2,3][5]int32 b1, b2; 76 | [2,3][5]int32 c; 77 | [5]int32 d; 78 | 79 | set_arrarr2(b1>>) ->> b1; 80 | b1[3][1,2][4] -> o[3]; 81 | b1[0][1,2][3] + b1[2][0,1][2] -> o[4]; 82 | 83 | b1[1] -> c; 84 | c[1,1][0] -> o[5]; 85 | 86 | { 87 | int32 i=0; 88 | while i<5 { i->d[i]; i+1->i; } 89 | } 90 | 91 | d -> c[d[0],d[1]]; 92 | c -> b1[d[1]]; 93 | b1 -> b2; 94 | b2[1][d[0],1][2] -> o[6]; 95 | 96 | b1[0] -> b2[1]; 97 | b2[1][0,1][2] -> o[7]; 98 | 99 | d ->> c[1,2]; 100 | c ->> b1[2]; 101 | b1 ->> b2; 102 | b2[2][1,2][3] -> o[8]; 103 | } 104 | 105 | muntrace(); 106 | 107 | printf("%d %d %d %d %d %d %d %d %d", 108 | o[0], o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8]); 109 | 110 | -------------------------------------------------------------------------------- /idea/Class.pa: -------------------------------------------------------------------------------- 1 | // Object pointer that not has details 2 | type FILE; 3 | type sqlite3; 4 | 5 | // Primitype type re-definition 6 | type int int32; 7 | type overwrite int int64; 8 | 9 | // struct 10 | type struct_tm {int32 tm_sec, tm_min, tm_hour} 11 | // initialize 12 | struct_tm t = { tm_sec:10, tm_min:20, tm_hour:1 } 13 | struct_tm t2 = [10, 20, 1]; 14 | // assign 15 | [10,20,1] -> t; 16 | ({tm_sec:10, tm_min:20, tm_hour:1}) -> t; 17 | 18 | interface bar { 19 | calc(bar b) -> int64; 20 | } 21 | 22 | // default implementation. it works like template. 23 | public func calc(bar b) -> int64 24 | { 25 | } 26 | 27 | type foo: bar { 28 | int16 sec1; // private 29 | io int64 a; 30 | out string s; 31 | byte sec2; // private 32 | out int64 x; 33 | } 34 | 35 | @Constractor 36 | func create_foo() -> foo 37 | { 38 | } 39 | 40 | public func calc(friend bar.foo f) -> int64 41 | { 42 | friend foo z; 43 | z.sec1 = 10; 44 | return z.sec1 * f.sec2; 45 | } 46 | 47 | foo f; 48 | baa b = f; 49 | baa b <<= f; 50 | baa.foo b; 51 | b.foo.a = 10; // down cast 52 | 53 | // vv old idea 54 | export class foo { 55 | data: 56 | int16 sec1; // private 57 | io int a; 58 | out string s; 59 | byte sec2; // private 60 | int x; 61 | 62 | method: 63 | /// foo constractor 64 | pub construct( 65 | int aa=0 /// aa value 66 | ) 67 | { 68 | return null; // if error 69 | } 70 | 71 | pub inline int result caloc() { 72 | return result = a*x; 73 | } 74 | 75 | void test() // private method 76 | { 77 | } 78 | } 79 | 80 | interface baa { 81 | data: 82 | foo:impl d; 83 | foo:impl arr[5]; 84 | foo ref; 85 | foo ref_arr[5]; 86 | method: 87 | } 88 | 89 | class string { 90 | data: 91 | byte cstr[]; // Unknown instance size. 92 | property: 93 | int len; 94 | method: 95 | construct(string src, uint buf_size=0); 96 | inline byte operator[](uint n) { 97 | return cstr[n]; 98 | } 99 | char operator()(uint n); 100 | } 101 | 102 | implement string { 103 | string construct(string src, uint buf_size) 104 | : cstr[buf_size?buf_size:src.size] 105 | { 106 | strcpy(src.cstr,this.cstr); 107 | } 108 | int len { 109 | return utl8_len(cstr); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/PlnScopeStack.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class PlnModule; 4 | class PlnFunction; 5 | class PlnBlock; 6 | class PlnVariable; 7 | 8 | enum PlnScpType { 9 | SC_MODULE, 10 | SC_FUNCTION, 11 | SC_BLOCK 12 | }; 13 | 14 | // use for parse. 15 | class PlnScopeItem 16 | { 17 | public: 18 | PlnScopeItem(PlnModule* m) : type(SC_MODULE) { inf.module = m; } 19 | PlnScopeItem(PlnFunction* f) : type(SC_FUNCTION) { inf.function = f; } 20 | PlnScopeItem(PlnBlock* b) : type(SC_BLOCK) { inf.block = b; } 21 | PlnScpType type; 22 | union { 23 | PlnModule *module; 24 | PlnFunction *function; 25 | PlnBlock *block; 26 | } inf; 27 | bool operator==(const PlnScopeItem &si) const 28 | { 29 | return (type == si.type && inf.block == si.inf.block); 30 | } 31 | }; 32 | 33 | typedef std::vector PlnScopeStack; 34 | 35 | // use for finishing 36 | enum PlnVarLifetime { 37 | VLT_NOTEXIST, 38 | VLT_UNKNOWN, 39 | VLT_ALLOCED, 40 | VLT_INITED, 41 | VLT_FREED, 42 | VLT_PARTLY_FREED 43 | }; 44 | 45 | class PlnScopeVarInfo { 46 | public: 47 | PlnVariable* var; 48 | PlnScopeItem scope; 49 | 50 | PlnVarLifetime lifetime; 51 | PlnScopeVarInfo(PlnVariable* v, PlnScopeItem s) 52 | :var(v), scope(s), lifetime(VLT_UNKNOWN) { }; 53 | }; 54 | 55 | class PlnScopeInfo { 56 | public: 57 | vector owner_vars; 58 | PlnScopeStack scope; 59 | void push_scope(PlnFunction* f) { scope.push_back(PlnScopeItem(f)); } 60 | void push_scope(PlnBlock* b) { scope.push_back(PlnScopeItem(b)); } 61 | void pop_scope() { scope.pop_back(); } 62 | void push_owner_var(PlnVariable* v) { owner_vars.push_back(PlnScopeVarInfo(v, scope.back())); } 63 | void pop_owner_vars(PlnBlock *b) { 64 | for (auto it=owner_vars.begin(); it!=owner_vars.end();) { 65 | if (it->scope.inf.block == b) it = owner_vars.erase(it); 66 | else ++it; 67 | } 68 | } 69 | void pop_owner_vars(PlnFunction *f) { 70 | for (auto it=owner_vars.begin(); it!=owner_vars.end();) { 71 | if (it->scope.inf.function == f) it = owner_vars.erase(it); 72 | else // ++it; // for global variable 73 | BOOST_ASSERT(false); 74 | } 75 | } 76 | 77 | bool exists_current(PlnVariable* v); 78 | void set_lifetime(PlnVariable* v, PlnVarLifetime lt); 79 | PlnVarLifetime get_lifetime(PlnVariable* v); 80 | }; 81 | -------------------------------------------------------------------------------- /src/test/pacode/020_arrlit.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | const N = 4; 4 | 5 | // int 6 | [3]int64 i1 = [1,2,3]; 7 | [3]int32 i21, i22 = [1,2,3], [-4,5,6]; 8 | [3]int16 i3 = [1u,2,3]; 9 | [3]sbyte i4 = [1,2,N-1]; 10 | 11 | printf("%d%d%d%d%d ", i1[1], i21[2], i22[0], i3[0], i4[2]); 12 | 13 | [4,5,6] -> i1; 14 | [4,5,6],[7,8,9] -> i21, i22; 15 | [4,5,6] -> i3; 16 | [4,5,6] -> i4; 17 | 18 | printf("%d%d%d%d%d ", i1[1], i21[2], i22[0], i3[0], i4[2]); 19 | 20 | // float 21 | [3]flo64 f1 = [1.1,2.2,3.3]; 22 | [3]flo32 f21, f22 = [1,2u,3], [4,5.5,6]; 23 | 24 | printf("%.1f %.1f %.1f\n", f1[2], f21[0], f22[1]); 25 | 26 | // 2 dimention 27 | [2,3]int32 ia1 = [1,2,3][4,5,6]; 28 | [2,3]int16 ia2, ia3 = [1,2,3][4,5,6], [7,8,9][10,11,12]; 29 | 30 | printf("%d%d%d ", ia1[1,1], ia2[1,2], ia3[0,0]); 31 | 32 | [2,3]flo64 fa1 = [1, 2.1e+2, 3][4, 5, 6]; 33 | printf("%.0f ", fa1[0,1]); 34 | 35 | [2,3]flo32 fa2 = [[1,2,3], [4,5,6]]; 36 | printf("%.0f%.0f ", fa2[1,0], fa2[1,2]); 37 | 38 | // 3 dimention 39 | [2,3,4]int64 iarr3 = 40 | [ [1,2,3,4][5,6,7,8][9,10,11,12] ] 41 | [ [-1,-2,-3,-4][-5,-6,-7,-8][-9,-10,-11,-12] ]; 42 | printf("%d%d%d ", iarr3[0,2,3], iarr3[1,1,1], iarr3[1,2,3]); 43 | 44 | [2,3,4]int64 iarr3a = 45 | [[1,2,3,4][5,6,7,8][9,10,11,12], 46 | [-1,-2,-3,-4][-5,-6,-7,-8][-9,-10,-11,-12]]; 47 | printf("%d%d%d ", iarr3a[0,2,3], iarr3a[1,1,1], iarr3a[1,2,3]); 48 | 49 | [2,3,4]int64 iarr3b = [ 50 | [[1,2,3,4], [5,6,7,8], [9,10,11,12]], 51 | [[-1,-2,-3,-4],[-5,-6,-7,-8],[-9,-10,-11,-12]] 52 | ]; 53 | printf("%d%d%d\n", iarr3b[0,2,3], iarr3b[1,1,1], iarr3b[1,2,3]); 54 | 55 | // 4 dimention 56 | [2,2,2,2]int64 iarr4 = [[[1,2][3,4]] [[5,6][7,8]]] [[[9,10][11,12]] [[13,14][15,16]]]; 57 | printf("%d%d ", iarr4[0,0,0,0], iarr4[1,1,1,1]); 58 | 59 | [ [[16,15][14,13]][[12,11][10,9]], [[8,7][6,5]][[4,3][2,1]]] -> iarr4; 60 | printf("%d%d ", iarr4[0,0,0,0], iarr4[1,1,1,1]); 61 | 62 | // 1x 63 | [1,3]int16 arr1 = [[1,2,3]]; 64 | [3,1]int16 arr1a = [1][2][3]; 65 | [3,1]int16 arr1b = [[1],[2],[3]]; 66 | [1,3,1]int16 arr1c = [[1][2][3]]; 67 | 68 | printf("%d%d", arr1[0,0], arr1[0,2]); 69 | printf("%d%d", arr1a[0,0], arr1a[2,0]); 70 | printf("%d%d", arr1b[0,0], arr1b[2,0]); 71 | printf("%d%d", arr1c[0,0,0], arr1c[0,2,0]); 72 | 73 | // text literal 74 | test("abc"); 75 | 76 | func test([10]byte text) 77 | { 78 | 68 -> text[1];// 68 (D) 79 | printf(" %s", text); 80 | } 81 | 82 | -------------------------------------------------------------------------------- /src/PlnMessage.h: -------------------------------------------------------------------------------- 1 | /// Message definitions. 2 | /// 3 | /// Manage output message descriptions in Palan compiler. 4 | /// 5 | /// @file PlnMessage.h 6 | /// @copyright 2017-2021 YAMAGUCHI Toshinobu 7 | 8 | #include 9 | using std::string; 10 | 11 | #define PAC_ERR_MSG_START_NO 100 12 | enum PlnErrCode { 13 | E_UndefinedVariable = PAC_ERR_MSG_START_NO, // var name 14 | E_UndefinedFunction, // func name 15 | E_UndefinedType, // type name 16 | E_NoMatchingFunction, // func name, candidates func 17 | E_DuplicateVarName, // var name 18 | E_DuplicateFunction, // func name 19 | E_NumOfLRVariables, // none 20 | E_InvalidRetValues, // none 21 | E_NeedRetValues, // none 22 | E_InvalidReturnValType, // var name 23 | E_CantCopyFreedVar, // var name 24 | E_CantCopyType, // type name 25 | E_AmbiguousFuncCall, // func name 26 | E_IncompatibleTypeAssign, // src type, dst type 27 | E_CantUseAtToplevel, // statement 28 | E_CantUseMoveOwnershipFrom, // var name 29 | E_CantUseMoveOwnershipTo, // var name 30 | E_CantCopyToReadonly, // var name 31 | E_CantDefineConst, // const name 32 | E_DuplicateConstName, // const name 33 | E_CantUseOperatorHere, // var name 34 | E_CantUseIndexHere, // var name 35 | E_AmbiguousVarType, // var name 36 | E_IncompatibleTypeInitVar, // var name 37 | E_UndefinedConst, // const name 38 | E_ValueRequired, // none 39 | E_NotWithInLoop, // none 40 | E_NoMatchingParameter, // none 41 | E_NoMemberName, // type name, member name 42 | E_CantUseReadonlyExHere, // none 43 | E_DuplicateTypeName, // type name 44 | E_RequireVarInit, // var name 45 | E_UnexpectedToken, // token 46 | E_CantUseDynamicVal, // var name 47 | E_CantUseNonMemoryValue, // var name 48 | E_OnlyAllowedIntegerHere, // none 49 | E_OnlyAllowedAnySizeAtFirst, // none 50 | E_CantAllocate, // type name 51 | E_InvalidAST, // source name, line 52 | 53 | // CUI errors 54 | E_CUI_NoInputFile, 55 | E_CUI_IncompatibleOpt, 56 | E_CUI_InvalidExecOpt, 57 | 58 | // Unsupported grammer 59 | E_UnsupportedGrammer // any, any 60 | }; 61 | 62 | enum PlnHelpCode { 63 | H_Help, 64 | H_Version, 65 | H_Assembly, 66 | H_Compile, 67 | H_Output, 68 | H_Execute, 69 | H_Input 70 | }; 71 | 72 | class PlnMessage 73 | { 74 | public: 75 | // Static terms 76 | static string floatNumber(); 77 | static string arrayValue(); 78 | 79 | static string getErr(PlnErrCode err_code, string arg1="\x01", string arg2="\x01"); 80 | static const char* getHelp(PlnHelpCode help_code); 81 | }; 82 | -------------------------------------------------------------------------------- /src/test/pacode/027_ccall.pa: -------------------------------------------------------------------------------- 1 | ccall printf(@[?]byte format, ...) -> int32; 2 | // ccall sprintf(@![?]byte dst, @[?]byte src, ...) -> int32; 3 | ccall sprintf(@, @[?]byte src, ... => [?]byte dst) -> int32; 4 | ccall strcpy([?]byte >>dst, @[?]byte src) -> [?]byte; 5 | ccall sscanf(@[?]byte str, @[?]byte format => ...) -> int32; 6 | ccall strcat([?]byte >>dst, @[?]byte src) -> [?]byte; 7 | ccall exit(int32 status); 8 | ccall strlen(@[?]byte str)->int32; 9 | 10 | ccall fopen(@[?]byte filename, @[?]byte mode) -> FILE; 11 | ccall fclose(FILE >>stream) -> int32; 12 | ccall fprintf(@FILE stream, @[?]byte format, ...) -> int32; 13 | ccall fscanf(@FILE stream, @[?]byte format => ...) -> int32; 14 | 15 | ccall time(uint64 tloc)->uint64; 16 | ccall localtime(@uint64 t) -> @struct_tm; 17 | 18 | ccall cos(flo64 x) -> flo64 :m; 19 | ccall tanf(flo32 x) -> flo32; 20 | 21 | ccall strtol(@[?]byte s, @, int32 base => @![?]byte endptr) -> int32; 22 | 23 | type FILE; 24 | extern @FILE stdout, stderr; 25 | type struct_tm { 26 | int32 tm_sec; 27 | int32 tm_min; 28 | int32 tm_hour; 29 | int32 tm_mday; 30 | int32 tm_mon; 31 | int32 tm_year; 32 | int32 tm_wday; 33 | int32 tm_yday; 34 | int32 tm_isdst; 35 | }; 36 | 37 | const filename = "out/027_outfile.txt"; 38 | 39 | [32]byte str1, str2buf; 40 | sprintf("abc%d%s%.2f\n", 123, "def", 1.23 => str1); 41 | [?]byte str2 <<= (str2buf ->> strcpy(str1)); 42 | str2 -> printf(); 43 | 44 | int32 i; 45 | flo32 f; 46 | "aa 99 bb 2.34" -> sscanf("%s %d %s %f" => str1, i, str2, f); 47 | str2 ->> strcat(str1) ->> str2; 48 | printf("%s %d %.2f %d\n", str2, i, f, strlen("str len")); 49 | 50 | FILE file <<= fopen(filename, "w"); 51 | file->fprintf("This is test."); 52 | fclose(file>>); 53 | 54 | fopen(filename, "r") ->> file; 55 | fscanf(file, "%s %s" => str1, str2) -> i; 56 | fclose(file>>); 57 | 58 | stdout->fprintf("%d:%s,%s\n", i, str1, str2); 59 | infunc("infunc\n"); 60 | 61 | uint64 t = time(0); 62 | @struct_tm tm = localtime(t); 63 | struct_tm tm2 = localtime(t); 64 | 65 | if tm.tm_sec >= 0 && tm.tm_sec <= 59 { printf("s") } 66 | if tm.tm_mon >= 0 && tm.tm_mon <= 11 { printf("m") } 67 | if tm.tm_year >= 119 && tm.tm_year <= 200 68 | && tm.tm_year == tm2.tm_year { printf("y") } 69 | 70 | printf("%.2lf %.2f", cos(1.23), tanf(3.14159265359/4)); 71 | 72 | @![?]byte rest_str; 73 | int32 l = strtol("1234 abc", 10 => rest_str); 74 | 75 | printf("%s %d", rest_str, l); 76 | 77 | exit(0); 78 | 79 | func infunc(@[?]byte str) 80 | { 81 | stdout->fprintf("%s", str); 82 | } 83 | -------------------------------------------------------------------------------- /src/models/PlnFunction.h: -------------------------------------------------------------------------------- 1 | /// Function model declaration. 2 | /// 3 | /// @file PlnFunction.h 4 | /// @copyright 2017-2021 YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnModel.h" 7 | 8 | enum PlnPassingMethod { 9 | FPM_UNKNOWN, 10 | 11 | FPM_IN_BYVAL, // primitive:default, object:# 12 | FPM_IN_BYREF, // primitive:@, object:@ or @! 13 | FPM_IN_BYREF_CLONE, // object:default 14 | FPM_IN_BYREF_MOVEOWNER, // object:>> 15 | FPM_IN_VARIADIC, // primitive:byVal, object:byRef 16 | FPM_OUT_BYREF, // primitive:default, object:default 17 | FPM_OUT_BYREFADDR, // object:@! 18 | FPM_OUT_BYREFADDR_GETOWNER, // object:>> 19 | FPM_OUT_VARIADIC, // primitive:byRef, object:byRef 20 | }; 21 | 22 | enum { 23 | PIO_UNKNOWN = 0, 24 | PIO_INPUT = 1, 25 | PIO_OUTPUT = 2, 26 | // PIO_IO = 3, // == PIO_INPUT | PIO_OUTPUT unused 27 | }; 28 | 29 | class PlnParameter { 30 | public: 31 | PlnVariable* var; 32 | PlnExpression* dflt_value; 33 | int index; 34 | int iomode; 35 | PlnPassingMethod passby; 36 | }; 37 | 38 | class PlnReturnValue { 39 | public: 40 | PlnVariable* local_var; 41 | PlnVarType* var_type; 42 | bool is_share_with_param; 43 | 44 | PlnReturnValue(PlnVariable *var, PlnVarType* var_type, bool is_share_with_param) 45 | : local_var(var), var_type(var_type), is_share_with_param(is_share_with_param) {} 46 | }; 47 | 48 | class PlnFunction 49 | { 50 | public: 51 | string name; 52 | string asm_name; 53 | int type; 54 | vector parameters; 55 | vector return_vals; 56 | PlnVarInit *retval_init; 57 | PlnLoc loc; 58 | union { 59 | struct { 60 | int id; 61 | } syscall; 62 | struct { 63 | int stack_size; 64 | } pln; 65 | } inf; 66 | PlnBlock* implement; 67 | PlnBlock* parent; 68 | bool has_va_arg; 69 | int call_count; 70 | bool generated; 71 | bool do_opti_regalloc = true; 72 | bool never_return = false; 73 | 74 | PlnFunction(int func_type, const string& func_name); 75 | PlnVariable* addRetValue(const string& rname, PlnVarType* rtype); 76 | PlnVariable* addParam(const string& pname, PlnVarType* ptype, int iomode, PlnPassingMethod pass_method, PlnExpression* defaultVal); 77 | 78 | vector getParamStrs() const; 79 | vector createArgDps(); 80 | vector createRetValDps(); 81 | 82 | void genAsmName(); 83 | void finish(PlnDataAllocator& da, PlnScopeInfo& si); // throw PlnCompileError; 84 | void gen(PlnGenerator& g); 85 | void clear(); 86 | 87 | static string getParamStr(PlnVarType* vtype, PlnPassingMethod passby); 88 | }; 89 | 90 | -------------------------------------------------------------------------------- /src/models/PlnBlock.h: -------------------------------------------------------------------------------- 1 | /// Block model declaration. 2 | /// 3 | /// @file PlnBlock.h 4 | /// @copyright 2017-2022 YAMAGUCHI Toshinobu 5 | 6 | #include "../PlnModel.h" 7 | #include "PlnExpression.h" 8 | 9 | class PlnStructMemberDef; 10 | 11 | class PlnArgInf { 12 | public: 13 | PlnVarType* var_type; 14 | int iomode; 15 | int opt; 16 | PlnArgInf(PlnVarType* var_type, int iomode, int opt) 17 | : var_type(var_type), iomode(iomode), opt(opt) {} 18 | }; 19 | 20 | // Block: Statements 21 | class PlnBlock { 22 | public: 23 | vector statements; 24 | vector variables; 25 | vector globals; 26 | vector free_vars; 27 | struct PlnConst { 28 | string name; 29 | PlnExpression *ex; 30 | }; 31 | vector consts; 32 | vector typeinfos; 33 | vector funcs; 34 | 35 | PlnModule* parent_module; 36 | PlnFunction* parent_func; 37 | PlnBlock* parent_block; 38 | PlnStatement* owner_stmt; 39 | PlnLoc loc; 40 | 41 | PlnBlock(); 42 | ~PlnBlock(); 43 | 44 | void setParent(PlnFunction* f); 45 | void setParent(PlnBlock* b); 46 | 47 | PlnVariable* declareVariable(const string& var_name, PlnVarType* var_type, bool do_check_ancestor_blocks); 48 | PlnVariable* getVariable(const string& var_name); 49 | 50 | PlnVariable* declareGlobalVariable(const string& var_name, PlnVarType* var_type, bool is_extern); 51 | PlnVariable* getGlobalVariable(const string& var_name); 52 | 53 | void declareConst(const string& name, PlnExpression *ex); // throw PlnCompileError 54 | PlnExpression* getConst(const string& name); 55 | 56 | void declareType(const string& type_name); 57 | void declareType(const string& type_name, vector& members); 58 | void declareAliasType(const string& type_name, PlnVarType* orig_type); 59 | 60 | PlnVarType* getType(const string& type_name, const string& mode); 61 | PlnVarType* getFixedArrayType(PlnVarType* item_type, vector& init_args, const string& mode); 62 | PlnBlock* getTypeDefinedBlock(PlnVarType* var_type); 63 | 64 | PlnFunction* getFunc(const string& func_name, vector &arg_infs); // throw PlnCompileError 65 | PlnFunction* getFuncProto(const string& func_name, vector& param_types); 66 | 67 | void addFreeVars(vector &free_vars, PlnDataAllocator& da, PlnScopeInfo& si); 68 | 69 | void finish(PlnDataAllocator& da, PlnScopeInfo& si); 70 | void gen(PlnGenerator& g); 71 | 72 | static string generateFuncName(string fname, vector ret_types, vector arg_types); 73 | }; 74 | -------------------------------------------------------------------------------- /src/test/pacode/025_array_value.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | 3 | i1 = 11; 4 | i2 = 12; 5 | [3]int64 a = [i1,2,3]; 6 | printf("%d%d", a[0], a[2]); 7 | 8 | [2,3]int32 b, c = 9 | [i1,2,3] 10 | [44,55,66], 11 | [11,22,33] 12 | [4,5,i2]; 13 | 14 | printf(" %d%d %d%d", b[0,0], b[1,2], c[0,0], c[1,2]); 15 | 16 | const FARR = [11.1,22.2]; 17 | [3,2]flo32 f = [[1.1, 1.2], FARR, [33, i1+i2]]; 18 | printf(" %.1f %.1f %.1f\n", f[0,0], f[1,1], f[2,1]); 19 | 20 | // type inference 21 | aa = [i1,2,3]; 22 | printf("%d%d", aa[0], aa[2]); 23 | 24 | [,]int32 bb, cc = 25 | [i1,2,3] 26 | [44,55,66], 27 | [11,22,33] 28 | [4,5,i2]; 29 | printf(" %d%d %d%d", bb[0,0], bb[1,2], cc[0,0], cc[1,2]); 30 | 31 | ff = [[1.1, 1.2], FARR, [33, i1+i2]]; 32 | printf(" %.1f %.1f %.1f", ff[0,0], ff[1,1], ff[2,1]); 33 | 34 | u = 11u; 35 | u2 = [u, 12u, 13u]; 36 | u3 = [u, 12u, 13]; // for default type inference signed int. 37 | printf(" %d %d\n", u2[2], u3[2]); 38 | 39 | // assignment 40 | [3+i1, i2, 23] -> a; 41 | printf("%d%d ", a[0], a[2]); 42 | 43 | [i1+5, add(i1,i2), i1] 44 | [4,5,6] -> b; 45 | printf("%d%d%d ", b[0,0], b[0,1], b[0,2]); 46 | 47 | [2,2,2]byte d; 48 | [[i1,12][21,22],[31,32][41,42]] -> d; 49 | printf("%d%d%d\n", d[0,0,0], d[1,0,0], d[1,1,1]); 50 | 51 | func add(int64 a, b) -> int64 a 52 | { 53 | a + b -> a; 54 | } 55 | 56 | // type compatible(overload) 57 | prnt([i1, i1+1, i1+2]); 58 | prnt([u, u+1u, u+2u]); 59 | prnt([i1+0.1,22.2]); 60 | prnt([b[1,0],i1,3]); 61 | 62 | prnt([u, u+1, i1+0.1]); 63 | prnt([u, u+0.2]); 64 | 65 | printf("\n"); 66 | 67 | [2]int64 a1, a2; 68 | [3]int64 b1, b2; 69 | [i1,i1+1], [i2+1,3,4] -> a1, b1 -> a2, b2; 70 | 71 | printf("%d %d %d %d", a1[0], a2[1], b1[0], b2[2]); 72 | 73 | i = 2; 74 | [4][2,3]int16 arr3; 75 | [i,2,(1->i)][4,5,6] -> arr3[i]; 76 | 77 | printf(" %d %d %d", arr3[1][0,0], arr3[1][0,2], arr3[1][1,2]); 78 | 79 | printf("\n"); 80 | [prnt(i+2), 3, prnt(i)]; 81 | 82 | func prnt([3]int64 a) 83 | { 84 | printf("%d %d,", a[0],a[2]); 85 | } 86 | 87 | func prnt([2]flo64 f) 88 | { 89 | printf("%.1f,", f[1]); 90 | } 91 | 92 | func prnt(int64 i)->int64 i 93 | { 94 | printf("%d ", i); 95 | } 96 | 97 | prntref([1,2,3]); 98 | func prntref(@[3]int64 a) 99 | { 100 | printf("%d %d", a[0],a[2]); 101 | } 102 | 103 | { 104 | arr4 = retlit(); 105 | arr5 = retlit2(); 106 | printf(" %d %d", arr4[1], arr5[2]); 107 | } 108 | 109 | func retlit() -> [3]int32 110 | { 111 | return [1,2,3]; 112 | } 113 | 114 | func retlit2() -> [3]int32 a 115 | { 116 | return [1,2,3]; 117 | } 118 | -------------------------------------------------------------------------------- /src/test/pacode/011_assignment.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | ccall setenv(...); 3 | ccall mtrace(); 4 | ccall muntrace(); 5 | 6 | 7 | // Primitive assignment. 8 | int32 p1, p2, p3, p4, p5; 9 | 1, 2u -> p1, p2; 10 | p1, p2 -> p3, p4; 11 | 12 | [2]int32 p6; 13 | 14 | printf("%d %d %d %d %d %d %d %d\n", 15 | p1, p2, p3, p4, (5->p5), p5, (p5+1->p6[1]), p6[1]); 16 | 17 | 18 | // Work value assignment. 19 | p1+p2, p2+2 -> p2, p3; // Note: Currently, p3 of p3+3 is 20 | // used after updated value. But spec would be change in future. 21 | printf("%d %d", p2, p3); 22 | 23 | p3 / 2, p3 % 2 -> p1, p4; 24 | printf(" %d %d\n", p1, p4); 25 | 26 | func intfunc(int16 a, b) -> int16 c, d 27 | { a+b -> c; a-b -> d; } 28 | 29 | intfunc(p1, p2) -> p3, p4; 30 | 31 | printf("%d %d\n", p3, p4); 32 | 33 | // Object copy(single layer) 34 | [3]int16 a1, a2, a3, a4; 35 | 9 -> a1[2]; 36 | // object copy 37 | a1 -> a2; 38 | a1[2] -> p1; 39 | a1[2] -> a2[3]; 40 | 41 | // Object move 42 | a1 ->> a3; 43 | 44 | printf("%d %d %d %d\n", a3[2], a2[2], a2[3], a1); 45 | 46 | // object copy 47 | [5][2][3]int32 arr, arr2; 48 | int32 z=0; 49 | 50 | 3->arr[1][0][2]; 51 | 9->arr2[3][0][1]; 52 | 53 | arr[z+1], arr2[3] -> arr2[2+z], arr[0]; 54 | 55 | printf("%d %d\n",arr2[2][0][2], arr[0][0][1]); 56 | 57 | // chain assign 58 | 3, 5, p1+1 -> p2, p3, p6[0] -> p6[1], p4, p5; 59 | 60 | printf("%d %d %d %d %d %d\n", 61 | p2, p3, p6[0], p6[1], p4, p5); 62 | 63 | { 64 | [3]byte aa, bb, ee, ff; 65 | [2][3]byte cc, dd; 66 | 67 | 68 | 3->aa[1]; 69 | 9->bb[2]; 70 | 71 | aa, bb -> cc[0], dd[1] -> ee, ff; 72 | 73 | printf("%d %d", ee[1], ff[2]); 74 | 75 | setenv("MALLOC_TRACE", "out/mtrace011-1", 1); 76 | mtrace(); 77 | 8->aa[0]; 78 | 4->bb[1]; 79 | 80 | aa, bb -> cc[0], dd[1] 81 | ->>ee, >>ff; 82 | 83 | muntrace(); 84 | 85 | printf(" %d %d", ee[0], ff[1]); 86 | 87 | setenv("MALLOC_TRACE", "out/mtrace011-2", 1); 88 | mtrace(); 89 | 90 | retbytes()-> aa, bb 91 | ->> cc[0], >>dd[1] 92 | -> cc[1], dd[0] 93 | -> ee, ff; 94 | muntrace(); 95 | 96 | printf(" %d %d", ee[1], ff[2]); 97 | 98 | setenv("MALLOC_TRACE", "out/mtrace011-3", 1); 99 | mtrace(); 100 | 6, 1 -> cc[0][1], dd[1][2]; 101 | 102 | cc[0], dd[1] ->> aa, >>bb 103 | -> ee, ff; 104 | muntrace(); 105 | printf(" %d %d\n", ee[1], ff[2]); 106 | 107 | setenv("MALLOC_TRACE", "out/mtrace011-4", 1); 108 | mtrace(); 109 | } 110 | muntrace(); 111 | 112 | func retbytes() -> [3]byte aa, bb , cc 113 | { 114 | 2->aa[1]; 115 | 7->bb[2]; 116 | 99->cc[0]; 117 | } 118 | -------------------------------------------------------------------------------- /idea/Function.pa: -------------------------------------------------------------------------------- 1 | alias int=int32; 2 | 3 | auto x,y = pointadd(1,2,3,4); 4 | print(x.str ":" y.str); 5 | swap(x,y) -> x, y; 6 | print(x.str ":" y.str); 7 | 8 | // コールチェーン(仮) 戻り値(expresion)と引数の前半の方が一致すれば 9 | // 関数を->でつなげれらる。 10 | 11 | string str1, str2 = "1\t2\t3", "3,4,5"; 12 | []string tmp = split(str1, "\t"); 13 | join(tmp1, ",") -> str1; 14 | // こうかける↓ 15 | str1 -> split("\t") -> join(",") -> str1; 16 | 17 | // メソッドコール 18 | // 第一引数と第一戻り値が同じ宣言の関数を使う場合、"."で引数/戻り値にセットしてコールできる。下記は全部同じ。 19 | replace(str1>>, "a", "b") ->> str1, count; 20 | str1->>replace("a", "b")->>str1, count; 21 | str1.replace("a","b") -> count; 22 | // 第一引数がコピーまたは変更なしの参照の場合にも"."は使えうるが採用しない."->"を使う。 23 | 24 | object o1, o3; 25 | @object o4; 26 | 27 | funco(o1,o2.clone, o3>>, o4, o5!) ->> o1; // 所有を渡したので、o3は無効. 28 | // 内部処理的にはo1の無効処理(null代入)は行わない。 29 | // <<, ioは飾り。宣言をを意識させる+関数宣言後置の場合の推測に使用 30 | // 式を書く場合は、&(ab+b), *(x+3) 31 | // 式により発生したテンポラリオブジェクトは 32 | // *の場合のみ関数実行後delete. 33 | // *の引数はreturnできない(clone必要->無印を使うこと)。 34 | 35 | o1 -> o2; // deep copy. 36 | o1 ->> o2; // 所有権を取られたので、o1は無効(null代入). 以降o1->o2はコンパイルエラー 37 | 38 | // o1.xx(); o3.xx(); // ここではこれはコンパイルエラーとなる 39 | 40 | o4 = o2 // 参照のみ。o4がスコープはずれてもdeteteされない。 41 | 42 | func2(x, y) -> x; 43 | 44 | // Policy: returnはrval, output用 45 | // parameterは inp:ut / io用 46 | // parameterのプリミティブ型(int等)は、基本コピー渡し、ioの場合は、参照渡しとなる。 47 | // parameterのオブジェクト型(string等)は参照渡しのみ。 48 | 49 | // multi return 50 | func pointadd(int sx, int sy int ax, int ay) 51 | -> int x, int y 52 | { 53 | x = sx + ax; 54 | y = sy + ay; 55 | return; 56 | } 57 | 58 | // simple swap 59 | func swap(int sx, sy) 60 | -> int x, y 61 | { 62 | return sy, sx; 63 | } 64 | 65 | // object 66 | func funco(object o1, >>o2, >>o3, @object o4, @!object o5) 67 | -> object o2 68 | { 69 | // o1 は rval input only.(clone would be created before func call and callee free it) 70 | // o2はrvalだか 戻り値なので通常deleteされない. 71 | // o3はrval. deleteされる. read/write lval.clone or &lval ならok. 72 | // o4はlval. deleteされない。 readonly。 clone直など名無しオブジェクトは渡せない 73 | // (名無しオブジェクトのスコープ次第。Statement終わりまでなら渡せるはず) 74 | // o5はlval. deleteされない。writable(非推奨) 75 | // *渡しの時は別スレッドなどで途中で破棄されないよう、caller側でコンパイラが警告する。 76 | // プリミティブ(int64等)には &*は使えない。 77 | 78 | return ; // returnはo2がrval 79 | } 80 | 81 | // 戻り値とパラメータは重複して同じ名前を使うことができる。 82 | // 入出力の意図の記述とレジスタの共有ができる。 83 | func func2(int a, int b) -> int a 84 | { 85 | a += b; 86 | } 87 | 88 | #object so.initobj(); // スタックに確保したオブジェクトの初期化 89 | initobj(so!); // この書き方もできる 90 | 91 | func initobj(@!object o) -> o 92 | { 93 | } 94 | -------------------------------------------------------------------------------- /src/test/pacode/016_varflo.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | ccall exit(int32 n); 3 | flo32 f = 3.14159265358979323846; 4 | flo64 d = 3.14159265358979323846; 5 | 6 | printf("%.8f %.8f\n", f, d); 7 | showflo8(f, d); 8 | showflo8(d, f); 9 | 10 | flo32 ff = f; 11 | flo64 dd = d; 12 | 13 | 4, -5 -> f, d -> showflo() -> ff,dd; 14 | printf("%.2f %.2f ", ff, dd); 15 | f, d -> d, f -> showflo(); 16 | 6u, 7u -> f, d -> showflo(); 17 | showflo(0.0, 0.0); 18 | showflo(8, 9) -> showflo(); 19 | printf("\n"); 20 | 21 | int32 i = 3.6; 22 | printf("%d %d %d %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f\n", 23 | 1, 2, i, 1.0, 2.0, 3.0, 4.0, 5.0, f, d, 8.0, 9.0); 24 | 25 | int64 i8, j8; 26 | -10, 11 -> i8, j8 -> f, d -> showflo(); 27 | uint64 u8, v8; 28 | 10, 11 -> u8, v8 -> ff, dd -> showflo(); 29 | i8, j8 -> showflo(); 30 | u8, v8 -> showflo(); 31 | f, d, ff, dd -> i8, j8, u8, v8; 32 | printf("%d %d %d %d ", i8, j8, u8, v8); 33 | i8+1 -> d; 34 | printf("%.1f\n", d); 35 | 36 | int32 i4, j4; 37 | -12, 13 -> i4, j4 -> f, d -> showflo(); 38 | uint32 u4, v4; 39 | 12, 13 -> u4, v4 -> ff, dd -> showflo(); 40 | i4, j4 -> showflo(); 41 | u4, v4 -> showflo(); 42 | f, d, ff, dd -> i4, j4, u4, v4; 43 | printf("%d %d %d %d\n", i4, j4, u4, v4); 44 | 45 | int16 i2, j2; 46 | -14, 15 -> i2, j2 -> f, d -> showflo(); 47 | uint16 u2, v2; 48 | 14, 15 -> u2, v2 -> ff, dd -> showflo(); 49 | i2, j2 -> showflo(); 50 | u2, v2 -> showflo(); 51 | f, d, ff, dd -> i2, j2, u2, v2; 52 | printf("%d %d %d %d\n", i2, j2, u2, v2); 53 | 54 | sbyte i1, j1; 55 | -16, 17 -> i1, j1 -> f, d -> showflo(); 56 | byte u1, v1; 57 | 16, 17 -> u1, v1 -> ff, dd -> showflo(); 58 | i1, j1 -> showflo(); 59 | u1, v1 -> showflo(); 60 | f, d, ff, dd -> i1, j1, u1, v1; 61 | printf("%d %d %d %d\n", i1, j1, u1, v1); 62 | 63 | 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 8.1 -> showInt(); 64 | -1.1, -2.1, -3.1, -4.1, 5.1, 6.1, 7.1, 8.1 65 | -> i1, i2, i4, i8, u1, u2, u4, u8 66 | -> showInt(); 67 | 68 | f, d, f, d, f, d, f, d -> showInt(); 69 | 70 | flo64 r1, r2, r3, r4, r5, r6, r7, r8, r9 = retFlo(); 71 | printf("%.1f %.1f %.1f\n", r1, r8, r9); 72 | 73 | func showflo8(flo32 f, flo64 d) 74 | { 75 | printf("%.8f %.8f\n", f, d); 76 | } 77 | 78 | func showflo(flo32 f, flo64 d) -> flo32 ff, flo64 dd 79 | { 80 | printf("%.2f %.2f ", f, d); 81 | 1.23 -> ff; 82 | 2.34 -> dd; 83 | } 84 | 85 | func showInt(sbyte i1, int16 i2, int32 i4, int64 i8, 86 | byte u1, uint16 u2, uint32 u4, uint64 u8) 87 | { 88 | printf("%d %d %d %d %u %u %u %u\n", i1, i2, i4, i8, u1, u2, u4, u8); 89 | } 90 | 91 | func retFlo() -> flo64 a, b, c, d, e, f, g, h, i 92 | { 93 | 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 -> a, b, c, d, e, f, g, h, i; 94 | } 95 | 96 | -------------------------------------------------------------------------------- /src/models/PlnModule.cpp: -------------------------------------------------------------------------------- 1 | /// Module model class definition. 2 | /// 3 | /// Module is root of model tree. 4 | /// Module includes function definitions and top level code. 5 | /// 6 | /// @file PlnModule.cpp 7 | /// @copyright 2017-2020 YAMAGUCHI Toshinobu 8 | 9 | #include 10 | #include "../PlnConstants.h" 11 | #include "../PlnDataAllocator.h" 12 | #include "../PlnGenerator.h" 13 | #include "../PlnScopeStack.h" 14 | #include "../PlnTreeBuildHelper.h" 15 | #include "PlnModule.h" 16 | #include "PlnBlock.h" 17 | #include "PlnFunction.h" 18 | #include "PlnVariable.h" 19 | #include "PlnStatement.h" 20 | #include "PlnType.h" 21 | 22 | using namespace std; 23 | 24 | PlnModule::PlnModule() 25 | { 26 | toplevel = new PlnBlock(); 27 | PlnTypeInfo::initBasicTypes(); 28 | toplevel->parent_module = this; 29 | max_jmp_id = -1; 30 | } 31 | 32 | PlnModule::~PlnModule() 33 | { 34 | for (auto f: functions) 35 | delete f; 36 | } 37 | 38 | int PlnModule::getJumpID() 39 | { 40 | return ++max_jmp_id; 41 | } 42 | 43 | void PlnModule::gen(PlnDataAllocator& da, PlnGenerator& g) 44 | { 45 | for (auto f : functions) 46 | f->genAsmName(); 47 | 48 | PlnScopeInfo si; 49 | si.scope.push_back(PlnScopeItem(this)); 50 | 51 | g.genSecReadOnlyData(); 52 | g.genSecText(); 53 | 54 | palan::exit(toplevel, 0); 55 | toplevel->finish(da, si); 56 | if (do_opti_regalloc) 57 | da.optimizeRegAlloc(); 58 | da.finish(); 59 | int stack_size = da.stack_size; 60 | 61 | // gen toplevel as main function 62 | string s=""; 63 | g.genEntryPoint(s); 64 | g.genLabel(s); 65 | g.genEntryFunc(); 66 | g.genLocalVarArea(stack_size); 67 | 68 | toplevel->gen(g); 69 | da.reset(); 70 | g.genMainReturn(); 71 | g.comment("end of toplevel"); 72 | g.comment(""); 73 | g.genEndFunc(); 74 | 75 | // Generate assembly of only the functions called. 76 | // Note: call_count will be incremented at FunctionCall finising. 77 | while(true) { 78 | PlnFunction *f = NULL; 79 | for (auto func : functions) { 80 | if (!func->generated && func->call_count > 0) { 81 | f = func; 82 | break; 83 | } 84 | } 85 | 86 | if (!f) break; 87 | 88 | f->do_opti_regalloc = do_opti_regalloc; 89 | 90 | f->finish(da, si); 91 | f->gen(g); 92 | f->clear(); 93 | da.reset(); 94 | f->generated = true; 95 | } 96 | 97 | for (auto f : functions) { 98 | if (!f->generated) { 99 | // Do only finishing to detect code error 100 | f->do_opti_regalloc = do_opti_regalloc; 101 | f->finish(da, si); 102 | f->clear(); 103 | da.reset(); 104 | } 105 | } 106 | 107 | BOOST_ASSERT(si.scope.size() == 1); 108 | BOOST_ASSERT(si.owner_vars.size() == 0); 109 | 110 | delete toplevel; 111 | toplevel = NULL; 112 | } 113 | 114 | -------------------------------------------------------------------------------- /src/test/cuiTestBase.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "cuiTestBase.h" 11 | 12 | int clean() 13 | { 14 | return system("rm -f out/cui/*"); 15 | } 16 | 17 | inline int getStatus(int ret_status) 18 | { 19 | if (WIFEXITED(ret_status)) { 20 | return WEXITSTATUS(ret_status); 21 | } else { 22 | return -1; 23 | } 24 | } 25 | 26 | void copy_file(const string &from_file_name, const string &to_file_name) 27 | { 28 | try { 29 | ifstream is(from_file_name, ios::in | ios::binary); 30 | if (is) { 31 | ofstream os(to_file_name, ios::out | ios::binary); 32 | 33 | istreambuf_iterator iit(is); 34 | istreambuf_iterator end; 35 | ostreambuf_iterator oit(os); 36 | copy(iit, end, oit); 37 | } 38 | } catch(exception &e) { 39 | // do nothing 40 | } 41 | } 42 | 43 | string build(const string &srcf) 44 | { 45 | return exec_pac(srcf, "-o", srcf, ""); 46 | } 47 | 48 | string exec_pac(string srcf, const string &preopt, string outf, 49 | const string &postopt, const string &srcdir) 50 | { 51 | string log_file = "out/cui/" + (srcf != "" ? srcf : "log"); 52 | 53 | if (outf != "") 54 | outf = "out/cui/" + outf; 55 | if (srcf != "") { 56 | copy_file(srcdir + srcf + ".pa", "out/cui/" + srcf + ".pa"); 57 | srcf = "out/cui/" + srcf + ".pa"; 58 | } 59 | 60 | string pac_cmd = "../pac " + srcf 61 | + " " + preopt + " "+ outf + " " + postopt 62 | + " >" + log_file + ".out 2>" + log_file + ".err"; 63 | 64 | int ret = getStatus(system(pac_cmd.c_str())); 65 | if (ret) return "err: "+to_string(ret); 66 | 67 | return "success"; 68 | } 69 | 70 | string outfile(string outf) 71 | { 72 | outf = "out/cui/"+outf; 73 | int out_fd = open(outf.c_str(), O_RDONLY); 74 | string result; 75 | if (out_fd != -1) { 76 | struct stat finf; 77 | 78 | if (fstat(out_fd, &finf) == 0) { 79 | if (finf.st_size < 10) 80 | result = "too small"; 81 | else 82 | result = "exists"; 83 | } else { 84 | result = "read fail"; 85 | } 86 | close(out_fd); 87 | } else { 88 | result = "not exists"; 89 | } 90 | return result; 91 | } 92 | 93 | string getFileStr(string file_path) 94 | { 95 | ifstream f(file_path); 96 | if (f.fail()) { 97 | return "Can't open test result: " + file_path; 98 | } 99 | stringstream sstr; 100 | sstr << f.rdbuf(); 101 | return sstr.str(); 102 | } 103 | 104 | string outstr(const string &srcf) 105 | { 106 | string out_file = "out/cui/" + srcf + ".out"; 107 | return getFileStr(out_file); 108 | } 109 | 110 | string errstr(const string &srcf) 111 | { 112 | string out_file = "out/cui/" + srcf + ".err"; 113 | return getFileStr(out_file); 114 | } 115 | 116 | -------------------------------------------------------------------------------- /src/PlnGenerator.cpp: -------------------------------------------------------------------------------- 1 | /// Assembly code generator class definition. 2 | /// 3 | /// @file PlnGenerator.cpp 4 | /// @copyright 2017-2020 YAMAGUCHI Toshinobu 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "PlnModel.h" 13 | #include "PlnDataAllocator.h" 14 | #include "PlnGenerator.h" 15 | 16 | void PlnGenerator::genLoadDp(PlnDataPlace* dp, bool load_save) 17 | { 18 | PlnDataPlace *src_dp; 19 | string src_cmt; 20 | if (dp->save_place) { 21 | if (!load_save) return; 22 | 23 | src_dp = dp->save_place; 24 | src_cmt = dp->src_place->cmt() + src_dp->cmt(); 25 | 26 | } else { 27 | src_dp = dp->src_place; 28 | src_cmt = src_dp->cmt(); 29 | } 30 | 31 | auto srce = getEntity(src_dp); 32 | auto dste = getEntity(dp); 33 | if (dp->load_address && !dp->save_place) { 34 | genLoadAddress(dste.get(), srce.get(), "address of " + src_cmt + " -> " + dp->cmt()); 35 | 36 | } else { 37 | genMove(dste.get(), srce.get(), src_cmt + " -> " + dp->cmt()); 38 | if (dp->do_clear_src && !dp->save_place) { 39 | vector> clr_es; 40 | clr_es.push_back(getEntity(src_dp)); 41 | genNullClear(clr_es); 42 | } 43 | } 44 | } 45 | 46 | void PlnGenerator::genSaveSrc(PlnDataPlace* dp) 47 | { 48 | auto save_dp = dp->save_place; 49 | if (save_dp) { 50 | auto src_dp = dp->src_place; 51 | BOOST_ASSERT(src_dp); 52 | 53 | auto save = getEntity(save_dp); 54 | auto srce = getEntity(src_dp); 55 | string opt_cmt = (save_dp == dp) ? " (accelerate)" : " for save"; 56 | 57 | if (dp->load_address) { 58 | genLoadAddress(save.get(), srce.get(), "address of " + src_dp->cmt() + " -> " + save_dp->cmt() + opt_cmt); 59 | } else { 60 | genMove(save.get(), srce.get(), src_dp->cmt() + " -> " + save_dp->cmt() + opt_cmt); 61 | if (dp->do_clear_src) { 62 | vector> clr_es; 63 | clr_es.push_back(getEntity(src_dp)); 64 | genNullClear(clr_es); 65 | } 66 | } 67 | } 68 | } 69 | 70 | void PlnGenerator::genSaveDp(PlnDataPlace* dp) { 71 | if (dp->save_place && dp != dp->save_place) { 72 | PlnDataPlace *src_dp; 73 | string src_cmt; 74 | 75 | src_dp = dp->save_place; 76 | src_cmt = dp->src_place->cmt() + src_dp->cmt(); 77 | 78 | auto srce = getEntity(src_dp); 79 | auto dste = getEntity(dp); 80 | genMove(dste.get(), srce.get(), src_cmt + " -> " + dp->cmt()); 81 | 82 | // Basically, save_place used for register usage confliction. 83 | // do_clear_src used for variable on stack memory. 84 | // and this case will happen at "f(arr>>, arr2[i]);". 85 | // Following code not requrired because two condition don't occur same time. 86 | 87 | //if (dp->do_clear_src) { 88 | // vector> clr_es; 89 | // clr_es.push_back(getEntity(src_dp)); 90 | // genNullClear(clr_es); 91 | //} 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/models/expressions/assignitem/PlnAssignObjectRefItem.h: -------------------------------------------------------------------------------- 1 | /// Assignment Item class definition. 2 | /// 3 | /// A single Src variables of object reference (not indirect access). 4 | /// Need to clear reference to null after move ownership. 5 | /// Saving src for swap assignment (e.g. a,b -> b,a). 6 | /// 7 | /// @file PlnAssignObjectRefItem.h 8 | /// @copyright 2018-2019 YAMAGUCHI Toshinobu 9 | 10 | class PlnAssignObjectRefItem : public PlnAssignItem 11 | { 12 | PlnExpression* src_ex; 13 | PlnClone* src_save; 14 | PlnDstItem* dst_item; 15 | 16 | public: 17 | PlnAssignObjectRefItem(PlnExpression* ex) 18 | : src_ex(ex), src_save(NULL), dst_item(NULL) { 19 | BOOST_ASSERT((ex->values[0].type == VL_VAR && !(ex->values[0].inf.var->is_indirect)) 20 | || ex->values[0].type == VL_LIT_STR); 21 | BOOST_ASSERT(ex->getDataType(0) == DT_OBJECT || ex->getDataType(0) == DT_OBJECT_REF); 22 | } 23 | 24 | ~PlnAssignObjectRefItem() { 25 | delete src_save; 26 | delete dst_item; 27 | } 28 | 29 | void addDstEx(PlnExpression* ex, bool need_save) override { 30 | BOOST_ASSERT(dst_item == NULL); 31 | 32 | dst_item = PlnDstItem::createDstItem(ex, need_save); 33 | } 34 | 35 | int addDataPlace(vector &data_places, int start_ind) override { 36 | dst_item->place = data_places[start_ind]; 37 | return start_ind + 1; 38 | } 39 | 40 | void finishS(PlnDataAllocator& da, PlnScopeInfo& si) override { 41 | int assgin_type = dst_item->getAssginType(); 42 | if (dst_item->need_save && assgin_type == ASGN_COPY) { 43 | src_save = new PlnClone(da, src_ex, src_ex->values[0].inf.var->var_type, true); 44 | PlnFinishRole fr = dst_item->setSrcEx(da, si, src_save); 45 | src_save->finishAlloc(da, si); 46 | src_ex->finish(da, si); 47 | src_save->finishCopy(da, si); 48 | BOOST_ASSERT(fr == FINISH_BY_DSTITEM); 49 | // No Case for Clone 50 | /* if (fr == FINISH_BY_ASSIGNITEM) { 51 | src_save->finish(da, si); 52 | } */ 53 | 54 | } else { 55 | PlnFinishRole fr = dst_item->setSrcEx(da, si, src_ex); 56 | if (fr == FINISH_BY_ASSIGNITEM) { 57 | src_ex->finish(da, si); 58 | } 59 | } 60 | 61 | if (assgin_type == ASGN_MOVE) { 62 | // Mark as freed variable. 63 | auto var = src_ex->values[0].inf.var; 64 | if (!si.exists_current(var)) 65 | si.push_owner_var(var); 66 | si.set_lifetime(var, VLT_FREED); 67 | } 68 | } 69 | 70 | void finishD(PlnDataAllocator& da, PlnScopeInfo& si) override { 71 | dst_item->finish(da, si); 72 | if (src_save) 73 | src_save->finishFree(da, si); 74 | } 75 | 76 | void genS(PlnGenerator& g) override { 77 | if (src_save) 78 | src_save->genAlloc(g); 79 | src_ex->gen(g); 80 | if (src_save) { 81 | src_save->genCopy(g); 82 | src_save->gen(g); 83 | } 84 | } 85 | 86 | void genD(PlnGenerator& g) override { 87 | dst_item->gen(g); 88 | if (src_save) 89 | src_save->genFree(g); 90 | } 91 | }; 92 | 93 | -------------------------------------------------------------------------------- /src/models/expressions/assignitem/PlnDstMoveObjectItem.h: -------------------------------------------------------------------------------- 1 | /// Assignment Item class definition. 2 | /// 3 | /// Single Dst object value need to be free 4 | /// before move ownership. 5 | /// 6 | /// @file PlnDstMoveObjectItem.h 7 | /// @copyright 2018-2019 YAMAGUCHI Toshinobu 8 | 9 | class PlnDstMoveObjectItem : public PlnDstItem 10 | { 11 | PlnExpression *dst_ex; 12 | PlnDataPlace *dst_dp; 13 | PlnExpression *free_ex; 14 | 15 | public: 16 | PlnDstMoveObjectItem(PlnExpression* ex) 17 | : dst_ex(ex), dst_dp(NULL), free_ex(NULL) 18 | { 19 | BOOST_ASSERT(ex->values.size() == 1); 20 | BOOST_ASSERT(ex->type == ET_VALUE); 21 | BOOST_ASSERT(ex->values[0].type == VL_VAR); 22 | BOOST_ASSERT(ex->getDataType(0) == DT_OBJECT_REF); 23 | 24 | if (ex->values[0].getVarType()->mode[IDENTITY_MD] != 'm') { 25 | PlnCompileError err(E_CantUseMoveOwnershipTo, ex->values[0].inf.var->name); 26 | throw err; 27 | } 28 | } 29 | 30 | ~PlnDstMoveObjectItem() { 31 | delete free_ex; 32 | } 33 | 34 | PlnAsgnType getAssginType() override { return ASGN_MOVE; } 35 | 36 | PlnFinishRole setSrcEx(PlnDataAllocator &da, PlnScopeInfo& si, PlnExpression *src_ex) override { 37 | int index = src_ex->data_places.size(); 38 | 39 | auto src_type = src_ex->values[index].getVarType(); 40 | auto dst_type = dst_ex->values[0].getVarType(); 41 | 42 | // It shoud be checked at buildAssignment of TreeBuilder 43 | BOOST_ASSERT(dst_type->canCopyFrom(src_type, ASGN_MOVE) & TC_CONV_OK); 44 | /*if (!(dst_type->canCopyFrom(src_type, ASGN_MOVE) & TC_CONV_OK)) { 45 | PlnCompileError err(E_CantUseMoveOwnershipTo, dst_ex->values[0].inf.var->name); 46 | err.loc = dst_ex->loc; 47 | throw err; 48 | }*/ 49 | 50 | dst_dp = dst_ex->values[0].getDataPlace(da); 51 | if (src_ex->values[index].type == VL_VAR 52 | && src_ex->values[index].inf.var != dst_ex->values[0].inf.var) { 53 | dst_dp->do_clear_src = true; 54 | } 55 | src_ex->data_places.push_back(dst_dp); 56 | return FINISH_BY_ASSIGNITEM; 57 | } 58 | 59 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override { 60 | if (need_save) { 61 | da.allocSaveData(dst_dp, dst_dp->push_src_step, dst_dp->release_step); 62 | } 63 | 64 | dst_ex->finish(da, si); 65 | auto var = dst_ex->values[0].inf.var; 66 | auto lt = si.get_lifetime(var); 67 | if (lt == VLT_ALLOCED || lt == VLT_INITED || lt == VLT_PARTLY_FREED) { 68 | free_ex = var->getFreeEx(); 69 | free_ex->finish(da, si); 70 | } 71 | 72 | BOOST_ASSERT(dst_dp->src_place); 73 | da.popSrc(dst_dp); 74 | si.set_lifetime(var, VLT_INITED); 75 | 76 | if (place) { 77 | da.pushSrc(place, dst_dp); 78 | 79 | } else { 80 | da.releaseDp(dst_dp); 81 | } 82 | } 83 | 84 | void gen(PlnGenerator& g) override { 85 | dst_ex->gen(g); 86 | if (free_ex) 87 | free_ex->gen(g); 88 | g.genLoadDp(dst_dp); 89 | if (place) { 90 | g.genSaveDp(place); 91 | } 92 | } 93 | }; 94 | 95 | -------------------------------------------------------------------------------- /samples/usesqlite.pa: -------------------------------------------------------------------------------- 1 | // std 2 | type FILE; 3 | type c_str = [?]byte; 4 | ccall printf(@c_str format, ...) -> int32; 5 | ccall strlen(@c_str str) -> int64; 6 | ccall exit(int32 status); 7 | 8 | // sqlite3 9 | type sqlite3; 10 | type sqlite3_stmt; 11 | ccall sqlite3_open(@c_str filename => sqlite3 db>>) -> int32:sqlite3; 12 | ccall sqlite3_close(sqlite3 >>db) -> int32; 13 | ccall sqlite3_errmsg(@sqlite3 db) -> @[?]byte; 14 | ccall sqlite3_prepare_v2(@sqlite3 db, @c_str sql, int32 nbyte, @, int64 tail_dummy=0 => sqlite3_stmt stmt>>) -> int32; 15 | ccall sqlite3_bind_int(@sqlite3_stmt stmt, int32 ind, int32 val) -> int32; 16 | ccall sqlite3_bind_text(@sqlite3_stmt stmt, int32 ind, @c_str str, int32 len, int64 destructor_type) -> int32; 17 | ccall sqlite3_step(@sqlite3_stmt stmt) -> int32; 18 | ccall sqlite3_column_int(@sqlite3_stmt stmt, int32 icol) -> int32; 19 | ccall sqlite3_column_text(@sqlite3_stmt stmt, int32 icol) -> @c_str; 20 | ccall sqlite3_reset(@sqlite3_stmt stmt) -> int32; 21 | ccall sqlite3_finalize(@sqlite3_stmt >>stmt) -> int32; 22 | const SQLITE_OK = 0; 23 | const SQLITE_NG = 1; 24 | const SQLITE_ROW = 100; 25 | const SQLITE_DONE = 101; 26 | const SQLITE_STATIC = 0; 27 | const SQLITE_TRANSIENT = -1; 28 | 29 | sqlite3 db; 30 | sqlite3_open(":memory:" =>> db) -> check(db, "open db"); 31 | { 32 | sqlite3_stmt tbl_stmt; 33 | sqlite3_prepare_v2(db, 34 | "CREATE TABLE fruits (" 35 | " id INTEGER PRIMARY KEY," 36 | " name TEXT NOT NULL" 37 | ");", 38 | -1, 0 =>> tbl_stmt) 39 | -> check(db, "table sql"); 40 | tbl_stmt->sqlite3_step() -> check(db, "create tbl"); 41 | tbl_stmt->>sqlite3_finalize() -> check(db, "finalize"); 42 | } 43 | 44 | { 45 | sqlite3_stmt ins_stmt; 46 | @c_str ins_sql = "INSERT INTO fruits VALUES(?, ?);"; 47 | sqlite3_prepare_v2(db, ins_sql, -1, 0 =>> ins_stmt) -> check(db, "insert sql"); 48 | 49 | const NUM = 2; 50 | []@c_str fruits = ["apple", "orange"]; 51 | i=0; 52 | while i check(db, "bind int"); 54 | sqlite3_bind_text(ins_stmt, 2, fruits[i], strlen(fruits[i]), SQLITE_STATIC) -> check(db, "bind txt"); 55 | ins_stmt->sqlite3_step() -> check(db, "insert dat"); 56 | ins_stmt->sqlite3_reset(); 57 | i + 1 -> i; 58 | } 59 | ins_stmt->>sqlite3_finalize() -> check(db, "finalize"); 60 | } 61 | { 62 | sqlite3_stmt sel_stmt; 63 | @c_str sel_sql = "SELECT * FROM fruits;"; 64 | sqlite3_prepare_v2(db, sel_sql, -1, 0 =>> sel_stmt) -> check(db, "select sql"); 65 | 66 | int32 rc; 67 | while (sel_stmt->sqlite3_step()->rc) == SQLITE_ROW { 68 | id = (sel_stmt -> sqlite3_column_int(0)); 69 | printf("%d: %s\n", id, sqlite3_column_text(sel_stmt, 1)); 70 | } 71 | rc -> check(db, "select all"); 72 | sel_stmt->>sqlite3_finalize() -> check(db, "finalize"); 73 | } 74 | 75 | db->>sqlite3_close(); 76 | 77 | func check(int32 ret_val, @sqlite3 db, @c_str method) { 78 | if ret_val != SQLITE_OK && ret_val != SQLITE_DONE { 79 | printf("%s error: %s\n", method, sqlite3_errmsg(db)); 80 | exit(1); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM=pac 2 | 3 | # NOTICE: Run 'make depend' after update SRCS. 4 | SRCS=palan.cpp \ 5 | models/PlnModule.cpp models/PlnFunction.cpp models/PlnBlock.cpp \ 6 | models/PlnStatement.cpp models/PlnExpression.cpp models/PlnVariable.cpp \ 7 | models/PlnType.cpp \ 8 | models/PlnLoopStatement.cpp \ 9 | models/PlnConditionalBranch.cpp \ 10 | models/types/PlnFixedArrayType.cpp \ 11 | models/types/PlnArrayValueType.cpp \ 12 | models/types/PlnStructType.cpp \ 13 | models/expressions/PlnFunctionCall.cpp \ 14 | models/expressions/PlnAddOperation.cpp \ 15 | models/expressions/PlnMulOperation.cpp \ 16 | models/expressions/PlnDivOperation.cpp \ 17 | models/expressions/PlnBoolExpression.cpp \ 18 | models/expressions/PlnCmpOperation.cpp \ 19 | models/expressions/PlnBoolOperation.cpp \ 20 | models/expressions/PlnAssignment.cpp \ 21 | models/expressions/PlnArrayItem.cpp \ 22 | models/expressions/PlnStructMember.cpp \ 23 | models/expressions/PlnReferenceValue.cpp \ 24 | models/expressions/PlnArrayValue.cpp \ 25 | models/expressions/PlnClone.cpp \ 26 | models/expressions/assignitem/PlnAssignItem.cpp \ 27 | generators/PlnX86_64Generator.cpp \ 28 | generators/PlnX86_64DataAllocator.cpp \ 29 | generators/PlnX86_64RegisterMachine.cpp \ 30 | generators/PlnX86_64RegisterSave.cpp \ 31 | generators/PlnX86_64CalcOptimization.cpp\ 32 | PlnDataAllocator.cpp PlnGenerator.cpp \ 33 | PlnMessage.cpp PlnTreeBuildHelper.cpp PlnScopeStack.cpp \ 34 | PlnModelTreeBuilder.cpp 35 | 36 | OBJS=$(notdir $(SRCS:.cpp=.o)) 37 | VPATH=.:objs:models:models/expressions:generators:models/expressions/assignitem:models/types 38 | AST=ast/pat 39 | TEST=test/tester 40 | POST_TEST=test/cuitester 41 | # Workarround of mtrace hang with double free. 42 | MALLOC_CHECK_=1 43 | export MALLOC_CHECK_ 44 | CXX_FLAGS= -g -O0 45 | CXX_RELEASE_FLAGS= -s -O2 46 | AST_MAKE_FLAGS= 47 | 48 | .SUFFIXES: .cpp .o 49 | 50 | FORCE: $(PROGRAM) 51 | @cd test && $(MAKE) post_test 52 | $(PROGRAM): $(OBJS) $(TEST) $(POST_TEST) test/*.c 53 | @cd test && $(MAKE) test 54 | @echo link $(PROGRAM). 55 | @$(CXX) $(LDFLAGS) -o $(PROGRAM) $(addprefix objs/,$(OBJS)) -lboost_program_options 56 | .cpp.o: 57 | @mkdir -p objs 58 | $(CXX) $(CFLAGS) -std=c++11 -c $(CXX_FLAGS) $< -o objs/$@ 59 | $(TEST): $(OBJS) test/*.cpp test/pacode/* $(AST) 60 | @$(MAKE) -C test "LDFLAGS=$(LDFLAGS)" 61 | $(AST): ast/*.cpp ast/*.yy ast/*.h ast/*.ll 62 | @$(MAKE) -C ast $(AST_MAKE_FLAGS) 63 | clean: 64 | rm -f objs/* 65 | rm -f $(AST) 66 | rm -f ast/objs/* 67 | rm -f test/*.o 68 | depend: $(SRCS) 69 | -@ $(RM) depend.inc 70 | -@ for i in $^; do $(CXX) -std=c++11 -MM $$i \ 71 | | sed "s/[_a-zA-Z0-9/][_a-zA-Z0-9/]*\.cpp//g" \ 72 | | sed "s/^\ /\t/g" >> depend.inc; done 73 | -include depend.inc 74 | .PHONY: release 75 | release: clean 76 | release: CXX_FLAGS=$(CXX_RELEASE_FLAGS) 77 | release: AST_MAKE_FLAGS=release 78 | release: $(PROGRAM) 79 | .PHONY: coverage 80 | coverage: CFLAGS=--coverage -DNDEBUG 81 | coverage: LDFLAGS=--coverage -lgcov 82 | coverage: FORCE 83 | 84 | -------------------------------------------------------------------------------- /src/models/expressions/PlnReferenceValue.cpp: -------------------------------------------------------------------------------- 1 | /// Reference value model class definition. 2 | /// 3 | /// PlnReferenceValue returns a value that indicated by reference. 4 | /// 5 | /// @file PlnReferenceValue.cpp 6 | /// @copyright 2020 YAMAGUCHI Toshinobu 7 | 8 | #include "boost/assert.hpp" 9 | #include "../../PlnConstants.h" 10 | #include "PlnReferenceValue.h" 11 | #include "../../PlnDataAllocator.h" 12 | #include "../../PlnGenerator.h" 13 | #include "../../PlnMessage.h" 14 | #include "../../PlnException.h" 15 | #include "../PlnVariable.h" 16 | #include "../PlnType.h" 17 | 18 | PlnReferenceValue::PlnReferenceValue(PlnExpression *refvar_ex) 19 | : PlnExpression(ET_REFVALUE), refvar_ex(refvar_ex) 20 | { 21 | BOOST_ASSERT(refvar_ex->values[0].type == VL_VAR); 22 | 23 | auto var = new PlnVariable(); 24 | auto ref_var = refvar_ex->values[0].inf.var; 25 | auto ref_vartype = ref_var->var_type; 26 | BOOST_ASSERT(ref_vartype->mode[ALLOC_MD] == 'r'); 27 | BOOST_ASSERT(ref_vartype->typeinf->type == TP_PRIMITIVE); 28 | 29 | var->name = ref_var->name + "@"; 30 | string mode = "---"; 31 | mode[ACCESS_MD] = ref_vartype->mode[ACCESS_MD]; 32 | var->var_type = ref_vartype->typeinf->getVarType(mode); // get default type 33 | 34 | BOOST_ASSERT(ref_var->container); 35 | var->container = ref_var->container; 36 | 37 | var->is_indirect = true; 38 | var->is_tmpvar = var->container->is_tmpvar; 39 | var->place = NULL; 40 | 41 | values.push_back(var); 42 | } 43 | 44 | PlnReferenceValue::~PlnReferenceValue() 45 | { 46 | delete refvar_ex; 47 | } 48 | 49 | PlnExpression* PlnReferenceValue::adjustTypes(const vector &types) 50 | { 51 | BOOST_ASSERT(types.size() == 1); 52 | PlnVarType *vtype = values[0].getVarType(); 53 | if (types[0]->canCopyFrom(vtype, ASGN_COPY) == TC_CANT_CONV) { 54 | PlnCompileError err(E_IncompatibleTypeAssign, vtype->tname(), types[0]->tname()); 55 | err.loc = loc; 56 | throw err; 57 | } 58 | 59 | if (types[0]->mode[ALLOC_MD] == 'r') { // lea (%src) %dst -> mov %src %dst 60 | auto ret_ex = refvar_ex; 61 | refvar_ex = NULL; 62 | delete this; 63 | return ret_ex; 64 | } 65 | 66 | return this; 67 | } 68 | 69 | void PlnReferenceValue::finish(PlnDataAllocator& da, PlnScopeInfo& si) 70 | { 71 | auto base_dp = da.prepareObjBasePtr(); 72 | refvar_ex->data_places.push_back(base_dp); 73 | refvar_ex->finish(da, si); 74 | 75 | auto ref_var = values[0].inf.var; 76 | if (!ref_var->place) { 77 | ref_var->place = new PlnDataPlace(ref_var->var_type->size(), ref_var->var_type->data_type()); 78 | ref_var->place->comment = &ref_var->name; 79 | } 80 | 81 | da.setIndirectObjDp(ref_var->place, base_dp, NULL, 0); 82 | 83 | da.popSrc(base_dp); 84 | if (data_places.size()) { 85 | da.pushSrc(data_places[0], ref_var->place); 86 | } 87 | } 88 | 89 | void PlnReferenceValue::gen(PlnGenerator& g) 90 | { 91 | auto base_dp = refvar_ex->data_places[0]; 92 | refvar_ex->gen(g); 93 | g.genLoadDp(base_dp, false); 94 | if (data_places.size()) { 95 | g.genSaveSrc(data_places[0]); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/models/expressions/assignitem/arrval_imp/PlnAssignArrayValue_Var.h: -------------------------------------------------------------------------------- 1 | /// Assignment Item class definition. 2 | /// 3 | /// @file PlnAssignArrayValue_Var.h 4 | /// @copyright 2019-2021 YAMAGUCHI Toshinobu 5 | 6 | class PlnAssignArrayValue_Var : public PlnAssignItem { 7 | PlnArrayValue* src_ex; 8 | PlnExpression* dst_ex; 9 | 10 | vector assign_items; 11 | PlnDataPlace *output_place; 12 | 13 | public: 14 | PlnAssignArrayValue_Var(PlnExpression* ex) 15 | : dst_ex(NULL), output_place(NULL) { 16 | BOOST_ASSERT(ex->type = ET_ARRAYVALUE); 17 | src_ex = static_cast(ex); 18 | } 19 | 20 | ~PlnAssignArrayValue_Var() { 21 | for (auto ai: assign_items) 22 | delete ai; 23 | } 24 | 25 | void addDstEx(PlnExpression* ex, bool need_save) override { 26 | BOOST_ASSERT(ex->values[0].type == VL_VAR); 27 | BOOST_ASSERT(ex->values[0].getVarType()->data_type() == DT_OBJECT_REF 28 | || ex->values[0].getVarType()->data_type() == DT_OBJECT); 29 | BOOST_ASSERT(!need_save); 30 | 31 | dst_ex = ex; 32 | } 33 | 34 | int addDataPlace(vector &data_places, int start_ind) override { 35 | output_place = data_places[start_ind]; 36 | return start_ind + 1; 37 | } 38 | 39 | void finishS(PlnDataAllocator& da, PlnScopeInfo& si) override { 40 | BOOST_ASSERT(dst_ex->values[0].asgn_type != ASGN_MOVE); 41 | BOOST_ASSERT(dst_ex->type == ET_VALUE); 42 | 43 | if (output_place) 44 | dst_ex->data_places.push_back(output_place); 45 | 46 | PlnVariable* dst_var = dst_ex->values[0].inf.var; 47 | vector val_items = src_ex->getAllItems(); 48 | vector dst_items; 49 | if (dst_var->var_type->typeinf->type == TP_FIXED_ARRAY) { 50 | dst_items = PlnArrayItem::getAllArrayItems(dst_ex->values[0].inf.var); 51 | 52 | } else if (dst_var->var_type->typeinf->type == TP_STRUCT) { 53 | dst_items = PlnStructMember::getAllStructMembers(dst_ex->values[0].inf.var); 54 | 55 | } else 56 | BOOST_ASSERT(false); 57 | 58 | BOOST_ASSERT(val_items.size() == dst_items.size()); 59 | 60 | for (int i=0; ivalues[0].getVarType(); 63 | if (dt->data_type() == DT_OBJECT_REF && dt->mode[ALLOC_MD] != 'h') 64 | dst_items[i]->values[0].asgn_type = ASGN_COPY_REF; 65 | else 66 | dst_items[i]->values[0].asgn_type = ASGN_COPY; 67 | ai->addDstEx(dst_items[i], false); 68 | assign_items.push_back(ai); 69 | } 70 | 71 | for (auto ai: assign_items) { 72 | ai->finishS(da, si); 73 | } 74 | } 75 | 76 | void finishD(PlnDataAllocator& da, PlnScopeInfo& si) override { 77 | for (auto ai: assign_items) { 78 | ai->finishD(da, si); 79 | } 80 | dst_ex->finish(da, si); 81 | } 82 | 83 | void genS(PlnGenerator& g) override { 84 | for (auto ai: assign_items) { 85 | ai->genS(g); 86 | } 87 | } 88 | 89 | void genD(PlnGenerator& g) override { 90 | for (auto ai: assign_items) { 91 | ai->genD(g); 92 | } 93 | dst_ex->gen(g); 94 | } 95 | }; 96 | 97 | -------------------------------------------------------------------------------- /src/models/expressions/assignitem/PlnAssignArrayValue.h: -------------------------------------------------------------------------------- 1 | /// Assignment Item class definition. 2 | /// 3 | /// @file PlnAssignArrayValue.h 4 | /// @copyright 2019-2021 YAMAGUCHI Toshinobu 5 | 6 | #include "arrval_imp/PlnAssignArrayValue_Static.h" 7 | #include "arrval_imp/PlnAssignArrayValue_Var.h" 8 | #include "arrval_imp/PlnAssignArrayValue_IndirectVar.h" 9 | 10 | class PlnAssignArrayValue : public PlnAssignItem { 11 | PlnArrayValue* src_ex; 12 | PlnExpression* dst_ex; 13 | PlnAssignItem *assign_item_imp; 14 | 15 | public: 16 | PlnAssignArrayValue(PlnExpression* ex) : assign_item_imp(NULL) { 17 | BOOST_ASSERT(ex->type = ET_ARRAYVALUE); 18 | src_ex = static_cast(ex); 19 | } 20 | 21 | ~PlnAssignArrayValue() { 22 | if (assign_item_imp) 23 | delete assign_item_imp; 24 | } 25 | 26 | void addDstEx(PlnExpression* ex, bool need_save) override { 27 | BOOST_ASSERT(ex->values[0].type == VL_VAR); 28 | BOOST_ASSERT(ex->values[0].getVarType()->data_type() == DT_OBJECT_REF 29 | || ex->values[0].getVarType()->data_type() == DT_OBJECT); 30 | BOOST_ASSERT(!need_save); 31 | 32 | dst_ex = ex; 33 | // create implementation object 34 | if (src_ex->doCopyFromStaticBuffer) { 35 | assign_item_imp = new PlnAssignArrayValue_Static(src_ex); 36 | 37 | } else { 38 | PlnVarType* t = dst_ex->values[0].inf.var->var_type; 39 | if (t->data_type() == DT_OBJECT_REF && t->mode[ALLOC_MD] != 'h') { 40 | // case @[3]int32 a = [1,x]; 41 | PlnCompileError err(E_CantUseDynamicVal, dst_ex->values[0].inf.var->name); 42 | err.loc = dst_ex->loc; 43 | throw err; 44 | } 45 | 46 | if (dst_ex->type == ET_VALUE) { 47 | assign_item_imp = new PlnAssignArrayValue_Var(src_ex); 48 | 49 | } else if (dst_ex->type == ET_ARRAYITEM || dst_ex->type == ET_STRUCTMEMBER) { 50 | assign_item_imp = new PlnAssignArrayValue_IndirectVar(src_ex); 51 | 52 | } else { 53 | BOOST_ASSERT(false); 54 | } 55 | } 56 | 57 | assign_item_imp->addDstEx(ex, need_save); 58 | } 59 | 60 | int addDataPlace(vector &data_places, int start_ind) override { 61 | BOOST_ASSERT(assign_item_imp); 62 | return assign_item_imp->addDataPlace(data_places, start_ind); 63 | } 64 | 65 | void finishS(PlnDataAllocator& da, PlnScopeInfo& si) override { 66 | BOOST_ASSERT(assign_item_imp); 67 | BOOST_ASSERT(dst_ex->values[0].asgn_type != ASGN_MOVE); 68 | 69 | // Check if distination is freed variable. 70 | if (dst_ex->type == ET_VALUE) { 71 | PlnVariable* var = dst_ex->values[0].inf.var; 72 | if (var->var_type->mode[2] == 'h' && si.get_lifetime(var) == VLT_FREED) { 73 | PlnCompileError err(E_CantCopyFreedVar, var->name); 74 | err.loc = dst_ex->loc; 75 | throw err; 76 | } 77 | } 78 | 79 | assign_item_imp->finishS(da, si); 80 | } 81 | 82 | void finishD(PlnDataAllocator& da, PlnScopeInfo& si) override { 83 | assign_item_imp->finishD(da, si); 84 | } 85 | 86 | void genS(PlnGenerator& g) override { 87 | assign_item_imp->genS(g); 88 | } 89 | 90 | void genD(PlnGenerator& g) override { 91 | assign_item_imp->genD(g); 92 | } 93 | }; 94 | 95 | -------------------------------------------------------------------------------- /src/test/pacode/028_struct.pa: -------------------------------------------------------------------------------- 1 | ccall printf(...); 2 | ccall setenv(...); 3 | ccall mtrace(); 4 | ccall muntrace(); 5 | 6 | type Test { 7 | int32 i32; 8 | byte b; 9 | int64 i64; 10 | flo32 f32; 11 | flo64 f64; 12 | }; 13 | 14 | type Test2 { 15 | int32 ti32; 16 | flo64 f64; 17 | Test test; 18 | [5]int16 arr16; 19 | }; 20 | 21 | int32 i, i2, i3, i4; 22 | int32 j, j2, j3, j4, j5; 23 | flo64 f, f2; 24 | int64 k, k2, k3; 25 | flo32 f3; 26 | flo64 f4; 27 | 28 | setenv("MALLOC_TRACE", "out/mtrace028", 1); 29 | Test t2; 30 | mtrace(); 31 | { 32 | // simple struct 33 | Test t; 34 | initTest(t>>)->>t; 35 | t.i32 -> i; 36 | t.b -> i2; 37 | t.i64 -> i3; 38 | t.f32 -> f; 39 | 40 | (t.i32 + t.b) * t.i64 -> i4; 41 | 42 | copyParam(t); 43 | refParam(t); 44 | t -> t2; 45 | 46 | // struct that have object member 47 | Test2 tt, tt2, tt3; 48 | 49 | i -> tt.test.i32; 50 | i2 -> tt.test.b; 51 | i3 -> tt.test.i64; 52 | 5.55 -> tt.test.f32; 53 | 54 | tt -> tt2; 55 | 56 | @Test2 reftt2 = tt2; 57 | tt2.test.i32 -> j; 58 | reftt2.test.b -> j2; 59 | tt2.test.i64 -> j3; 60 | 61 | tt2.test ->> t; 62 | t.f32 -> f2; 63 | 64 | [5]int16 ar = [1,2,3,4,5]; 65 | ar ->> tt2.arr16; 66 | tt2.arr16[4] -> j4; 67 | 68 | tt2.arr16 -> tt3.arr16; 69 | tt3.arr16[0] -> j5; 70 | 71 | // struct array 72 | [5]Test tarr; 73 | 10 -> tarr[0].f32; 74 | tarr[0].f32 -> k; 75 | 76 | // complex struct array 77 | x = 99; 78 | const TEST2_VAL = [11, 1.23, [21,22,23,24.4,12.3], [31,32,33,34,35] ]; 79 | const TEST2_VALx2 = [TEST2_VAL, TEST2_VAL]; 80 | [2][3,2]Test2 cmplxarr = 81 | [[TEST2_VALx2, TEST2_VALx2, TEST2_VALx2]] 82 | [ 83 | [ 84 | TEST2_VALx2,TEST2_VALx2, 85 | [ TEST2_VAL, [11, 1.23, [21,22,23,24.4,3.44], [31,32,33,34,x]] ] 86 | ] 87 | ]; 88 | 89 | cmplxarr[0][1,1].test.i32 -> k2; 90 | cmplxarr[0][1,1].test.f32 -> f3; 91 | cmplxarr[1][2,1].arr16[4] -> k3; 92 | cmplxarr[1][2,1].test.f64 -> f4; 93 | 94 | // ArrayValue for Test 95 | copyParam([1,2,3,3.3,4.4]); 96 | // ArrayValue for Test2 97 | copyParam([1, 2.22, [1,2,3,4,2.2],[1,2,3,4,5]]); 98 | 99 | Test ct = creTest(); 100 | } 101 | 102 | muntrace(); 103 | printf("%d %d %d %.2f\n", t2.i32, t2.b, t2.i64, t2.f32); 104 | printf("%d %d %d %.2f %d\n", i, i2, i3, f, i4); 105 | printf("%d %d %d %.2f %d %d\n", j, j2, j3, f2, j4, j5); 106 | printf("%d %d %d %.2f %.2f", k, k2, k3, f3, f4); 107 | 108 | func initTest(Test >>t) -> Test t 109 | { 110 | 32 -> t.i32; 111 | 1 -> t.b; 112 | 64 -> t.i64; 113 | 1.23 -> t.f32; 114 | } 115 | 116 | func copyParam(Test t) 117 | { 118 | 99 -> t.i32; 119 | 99 -> t.b; 120 | 99 -> t.i64; 121 | 99.9 -> t.f32; 122 | } 123 | 124 | // Dummy 125 | func copyParam(Test2 t) 126 | { 127 | } 128 | 129 | type Test3 { 130 | [2]int32 a; 131 | int32 b; 132 | int32 c; 133 | int32 d; 134 | }; 135 | 136 | type Test4 { 137 | int64 a, b; 138 | [4]int16 x, y; 139 | }; 140 | 141 | Test4 t4; 142 | 12 -> t4.y[3]; 143 | 144 | 145 | func copyParam(Test3 t) 146 | { 147 | } 148 | 149 | func refParam(@Test t) 150 | { 151 | if t.i32 != 32 { 152 | printf("ng"); 153 | } 154 | } 155 | 156 | func creTest() -> Test 157 | { 158 | return [1, 2, 3, 4.4, 5.5]; 159 | } 160 | -------------------------------------------------------------------------------- /src/generators/PlnX86_64CalcOptimization.cpp: -------------------------------------------------------------------------------- 1 | /// x86-64 (Linux) calculation optimization definitions. 2 | /// 3 | /// @file PlnX86_64CalcOptimization.h 4 | /// @copyright 2021 YAMAGUCHI Toshinobu 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "../PlnModel.h" 12 | #include "../PlnConstants.h" 13 | #include "PlnX86_64DataAllocator.h" 14 | #include "PlnX86_64Generator.h" 15 | 16 | inline int log2u(unsigned int x) 17 | { 18 | int r = -1; 19 | while (x) { 20 | ++r; 21 | x /= 2; 22 | } 23 | return r; 24 | } 25 | 26 | bool tryOptiMul(PlnX86_64RegisterMachine &m, PlnGenEntity* tgt, PlnGenEntity* scnd, string& comment) 27 | { 28 | if (scnd->type != GA_CODE) 29 | return false; 30 | 31 | if (tgt->data_type == DT_FLOAT) 32 | return false; 33 | 34 | if (scnd->data_type == DT_UINT || scnd->data_type == DT_SINT) { 35 | int64_t n = int64_of(scnd->ope); 36 | int64_t mask = n-1; 37 | if (n>0 && !(n&mask)) { // Check if n == 2^x 38 | BOOST_ASSERT(tgt->type == GA_REG); 39 | int shift_num = log2u(n); 40 | m.push(SALQ, imm(shift_num), ope(tgt), comment); 41 | return true; 42 | 43 | } 44 | } 45 | return false; 46 | } 47 | 48 | bool tryOptiDiv(PlnX86_64RegisterMachine &m, PlnGenEntity* tgt, PlnGenEntity* scnd, string& comment) 49 | { 50 | if (scnd->type != GA_CODE) 51 | return false; 52 | 53 | if (tgt->data_type == DT_FLOAT) 54 | return false; 55 | 56 | if (scnd->data_type == DT_UINT || scnd->data_type == DT_SINT) { 57 | int64_t n = int64_of(scnd->ope); 58 | int64_t mask = n-1; 59 | if (n>0 && !(n&mask)) { // Check if n == 2^x 60 | if (tgt->data_type == DT_UINT) { 61 | BOOST_ASSERT(tgt->type == GA_REG); 62 | int shift_num = log2u(n); 63 | m.push(SHRQ, imm(shift_num), ope(tgt), comment); 64 | return true; 65 | } else { 66 | BOOST_ASSERT(tgt->data_type == DT_SINT); 67 | BOOST_ASSERT(tgt->size == 8); 68 | int shift_num = log2u(n); 69 | m.push(MOVQ, ope(tgt), reg(RDX)); 70 | m.push(SHRQ, imm(64-shift_num), ope(tgt)); 71 | m.push(ADDQ, reg(RDX), ope(tgt)); 72 | m.push(SARQ, imm(shift_num), ope(tgt)); 73 | return true; 74 | } 75 | } 76 | } 77 | return false; 78 | } 79 | 80 | 81 | bool tryOptiMod(PlnX86_64RegisterMachine &m, PlnGenEntity* tgt, PlnGenEntity* scnd, string& comment) 82 | { 83 | if (scnd->type != GA_CODE) 84 | return false; 85 | 86 | if (scnd->data_type == DT_UINT || scnd->data_type == DT_SINT) { 87 | int64_t n = int64_of(scnd->ope); 88 | int64_t mask = n-1; 89 | if (n>0 && !(n&mask)) { // Check if n == 2^x 90 | BOOST_ASSERT(tgt->type == GA_REG); 91 | if (tgt->data_type == DT_UINT) { 92 | m.push(ANDQ, imm(mask), ope(tgt), comment); 93 | return true; 94 | 95 | } else { 96 | BOOST_ASSERT(tgt->data_type == DT_SINT); 97 | BOOST_ASSERT(tgt->size == 8); 98 | int shift_num = 64 - log2u(n); 99 | m.push(CLTQ); 100 | m.push(SHRQ, imm(shift_num), reg(RDX)); 101 | m.push(ADDQ, reg(RDX), ope(tgt)); 102 | m.push(ANDQ, imm(mask), ope(tgt), comment); 103 | m.push(SUBQ, reg(RDX), ope(tgt)); 104 | 105 | return true; 106 | } 107 | } 108 | } 109 | 110 | return false; 111 | } 112 | -------------------------------------------------------------------------------- /src/models/expressions/assignitem/PlnDstPrimitiveItem.h: -------------------------------------------------------------------------------- 1 | /// Assignment Item class definition. 2 | /// 3 | /// Dst value don't need to be free. 4 | /// Target: Integer variable(direct/indirect), 5 | /// Refernce copy. 6 | /// 7 | /// @file PlnDstPrimitiveItem.h 8 | /// @copyright 2018-2020 YAMAGUCHI Toshinobu 9 | 10 | class PlnDstPrimitiveItem : public PlnDstItem { 11 | PlnExpression *dst_ex; 12 | PlnDataPlace *dst_dp; 13 | PlnVariable *save_src_var; 14 | 15 | public: 16 | PlnDstPrimitiveItem(PlnExpression* ex) 17 | : dst_ex(ex), dst_dp(NULL), save_src_var(NULL) { 18 | BOOST_ASSERT(ex->values[0].type == VL_VAR); 19 | BOOST_ASSERT(ex->values[0].asgn_type != ASGN_MOVE); 20 | } 21 | 22 | ~PlnDstPrimitiveItem() { 23 | delete save_src_var; 24 | } 25 | 26 | PlnAsgnType getAssginType() override { return dst_ex->values[0].asgn_type; } 27 | 28 | PlnFinishRole setSrcEx(PlnDataAllocator &da, PlnScopeInfo &si, PlnExpression *src_ex) override { 29 | dst_dp = dst_ex->values[0].getDataPlace(da); 30 | if (place == NULL) { 31 | int val_ind = src_ex->data_places.size(); 32 | src_ex->data_places.push_back(dst_dp); 33 | if (src_ex->getDataType(val_ind) != DT_OBJECT_REF) { 34 | // DT_SINT/DT_UINT/DT_FLOAT 35 | if (dst_dp->data_type == DT_OBJECT_REF) { 36 | auto allocmode = src_ex->values[0].inf.var->var_type->mode[ALLOC_MD]; 37 | if (allocmode != 'r') { 38 | dst_dp->load_address = true; 39 | } 40 | } 41 | } 42 | 43 | } else { 44 | if (src_ex->type == ET_VALUE) { 45 | BOOST_ASSERT(src_ex->data_places.size() == 0); 46 | } 47 | 48 | if (dst_ex->type == ET_VALUE) { 49 | src_ex->data_places.push_back(dst_dp); 50 | 51 | } else { // e.g. ET_ARRAYITEM. save_src_var is use also return value. 52 | PlnVarType* t = dst_ex->values[0].inf.var->var_type; 53 | save_src_var = PlnVariable::createTempVar(da, t, "(save src)"); 54 | src_ex->data_places.push_back(save_src_var->place); 55 | } 56 | } 57 | return FINISH_BY_ASSIGNITEM; 58 | } 59 | 60 | void finish(PlnDataAllocator& da, PlnScopeInfo& si) override { 61 | BOOST_ASSERT((!save_src_var && dst_dp->src_place) 62 | || (save_src_var && save_src_var->place->src_place)); 63 | dst_ex->finish(da, si); 64 | 65 | if (save_src_var) { 66 | BOOST_ASSERT(place); 67 | // 1. src -> save_src_var 68 | // 2. save_src_var -> dst 69 | // 3. save_src_var -> parent dst 70 | 71 | da.popSrc(save_src_var->place); 72 | da.pushSrc(dst_dp, save_src_var->place, false); 73 | da.popSrc(dst_dp); 74 | da.releaseDp(dst_dp); 75 | da.pushSrc(place, save_src_var->place); 76 | 77 | } else { 78 | if (need_save) 79 | da.allocSaveData(dst_dp, dst_dp->push_src_step, dst_dp->release_step); 80 | 81 | da.popSrc(dst_dp); 82 | if (place) 83 | da.pushSrc(place, dst_dp); 84 | else 85 | da.releaseDp(dst_dp); 86 | } 87 | } 88 | 89 | void gen(PlnGenerator& g) override { 90 | dst_ex->gen(g); 91 | 92 | if (save_src_var) { 93 | g.genLoadDp(save_src_var->place); 94 | g.genLoadDp(dst_dp); 95 | g.genSaveSrc(place); 96 | 97 | } else { 98 | g.genLoadDp(dst_dp); 99 | if (place) g.genSaveSrc(place); 100 | } 101 | } 102 | }; 103 | 104 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at tos-yama@sa2.so-net.ne.jp. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /src/models/expressions/PlnBoolExpression.cpp: -------------------------------------------------------------------------------- 1 | /// PlnBoolExpression model class definisson. 2 | /// 3 | /// @file PlnBoolExpression 4 | /// @copyright 2020 YAMAGUCHI Toshinobu 5 | 6 | #include 7 | #include "../../PlnConstants.h" 8 | #include "PlnCmpOperation.h" 9 | #include "../PlnType.h" 10 | #include "../../PlnDataAllocator.h" 11 | #include "../../PlnGenerator.h" 12 | 13 | PlnBoolExpression* PlnBoolExpression::create(PlnExpression* e) 14 | { 15 | PlnBoolExpression* be = dynamic_cast(e); 16 | if (be) return be; 17 | 18 | if (e->type == ET_VALUE) { 19 | BOOST_ASSERT(e->values.size() == 1); 20 | 21 | PlnValType vtype = e->values[0].type; 22 | if (vtype == VL_LIT_INT8 || vtype == VL_LIT_UINT8) { 23 | if (e->values[0].inf.intValue == 0) { 24 | delete e; 25 | return new PlnFalseExpression(); 26 | } 27 | delete e; 28 | return new PlnTrueExpression(); 29 | } else if (vtype == VL_LIT_FLO8) { 30 | if (e->values[0].inf.floValue == 0.0) { 31 | delete e; 32 | return new PlnFalseExpression(); 33 | } 34 | delete e; 35 | return new PlnTrueExpression(); 36 | } 37 | } 38 | 39 | return new PlnCmpOperation(e, new PlnExpression(int64_t(0)), CMP_NE); 40 | } 41 | 42 | // PlnTrueExpression 43 | PlnTrueExpression::PlnTrueExpression() : PlnBoolExpression(ET_TRUE) 44 | { 45 | PlnValue v; 46 | v.type = VL_LIT_INT8; 47 | v.asgn_type = NO_ASGN; 48 | v.inf.intValue = 1; 49 | values.push_back(v); 50 | } 51 | 52 | void PlnTrueExpression::finish(PlnDataAllocator& da, PlnScopeInfo& si) 53 | { 54 | if (data_places.size()) { 55 | BOOST_ASSERT(data_places.size() == 1); 56 | if ((push_mode == -1 && !is_not) || push_mode == 1) { 57 | da.pushSrc(data_places[0], da.getLiteralIntDp(1)); 58 | } else { 59 | da.pushSrc(data_places[0], da.getLiteralIntDp(0)); 60 | } 61 | if (push_mode != -1) { 62 | BOOST_ASSERT(jmp_if != -1); 63 | da.popSrc(data_places[0]); 64 | } 65 | } 66 | } 67 | 68 | void PlnTrueExpression::gen(PlnGenerator& g) 69 | { 70 | if (data_places.size()) { 71 | g.genSaveSrc(data_places[0]); 72 | if (push_mode != -1) { 73 | g.genLoadDp(data_places[0]); 74 | } 75 | } 76 | 77 | if ((!is_not && jmp_if == 1) || (is_not && jmp_if == 0)) { 78 | g.genJump(jmp_id, "true"); 79 | } 80 | } 81 | 82 | // PlnFalseExpression 83 | PlnFalseExpression::PlnFalseExpression() : PlnBoolExpression(ET_FALSE) 84 | { 85 | PlnValue v; 86 | v.type = VL_LIT_INT8; 87 | v.asgn_type = NO_ASGN; 88 | v.inf.intValue = 0; 89 | values.push_back(v); 90 | } 91 | 92 | void PlnFalseExpression::finish(PlnDataAllocator& da, PlnScopeInfo& si) 93 | { 94 | if (data_places.size()) { 95 | BOOST_ASSERT(data_places.size() == 1); 96 | if ((push_mode == -1 && is_not) || push_mode == 1) { 97 | da.pushSrc(data_places[0], da.getLiteralIntDp(1)); 98 | } else { 99 | da.pushSrc(data_places[0], da.getLiteralIntDp(0)); 100 | } 101 | 102 | if (push_mode != -1) { 103 | BOOST_ASSERT(jmp_if != -1); 104 | da.popSrc(data_places[0]); 105 | } 106 | } 107 | } 108 | 109 | void PlnFalseExpression::gen(PlnGenerator& g) 110 | { 111 | if (data_places.size()) { 112 | g.genSaveSrc(data_places[0]); 113 | if (push_mode != -1) { 114 | g.genLoadDp(data_places[0]); 115 | } 116 | } 117 | 118 | if ((!is_not && jmp_if == 0) || (is_not && jmp_if == 1)) { 119 | g.genJump(jmp_id, "false"); 120 | } 121 | } 122 | 123 | -------------------------------------------------------------------------------- /src/ast/palanast.cpp: -------------------------------------------------------------------------------- 1 | /// Palan AST tool. 2 | /// 3 | /// Call lexcer, parser and generate AST json. 4 | /// 5 | /// @file palanast.cpp 6 | /// @copyright 2018-2019 YAMAGUCHI Toshinobu 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "PlnParser.hpp" 16 | #include "PlnLexer.h" 17 | #include "PlnAstMessage.h" 18 | #include "../../libs/json/single_include/nlohmann/json.hpp" 19 | 20 | using std::cout; 21 | using std::cerr; 22 | using std::endl; 23 | using std::exception; 24 | using std::ifstream; 25 | using std::ofstream; 26 | using std::ostream; 27 | using std::stringstream; 28 | using palan::PlnParser; 29 | using json = nlohmann::json; 30 | 31 | namespace po = boost::program_options; 32 | 33 | static string getDirName(string fpath); 34 | static string getFileName(string& fpath); 35 | 36 | int main(int argc, char* argv[]) 37 | { 38 | po::options_description opt("Options"); 39 | po::positional_options_description p_opt; 40 | po::variables_map vm; 41 | 42 | opt.add_options() 43 | ("help,h", PlnAstMessage::getHelp(H_Help)) 44 | ("output,o", po::value(), PlnAstMessage::getHelp(H_Output)) 45 | ("indent,i", PlnAstMessage::getHelp(H_Indent)) 46 | ("input-file", po::value>(), PlnAstMessage::getHelp(H_Input)); 47 | 48 | p_opt.add("input-file", -1); 49 | 50 | try { 51 | po::store(po::command_line_parser(argc, argv) 52 | .options(opt).positional(p_opt).run(), vm); 53 | } catch (exception &e) { 54 | cerr << "error: " << e.what() << endl; 55 | cerr << opt; 56 | return -1; 57 | } 58 | 59 | po::notify(vm); 60 | 61 | if (vm.count("help") || vm.count("input-file")!=1) { 62 | cout << opt; 63 | return 0; 64 | } 65 | 66 | int indent = -1; 67 | if (vm.count("indent")) { 68 | indent = 2; 69 | } 70 | 71 | ostream *jout = &cout; 72 | ofstream of; 73 | if (vm.count("output")) { 74 | string out_file = vm["output"].as(); 75 | of.open(out_file); 76 | if (of) { 77 | jout = &of; 78 | } 79 | } 80 | 81 | vector files(vm["input-file"].as< vector >()); 82 | string fname = files[0]; 83 | ifstream f; 84 | f.open(fname); 85 | if (f) { 86 | PlnLexer lexer; 87 | lexer.set_filename(fname); 88 | lexer.switch_streams(&f, &cout); 89 | 90 | json ast; 91 | 92 | PlnParser parser(lexer,ast); 93 | int res = parser.parse(); 94 | 95 | // set src files infomation. 96 | json files; 97 | int id = 0; 98 | for (auto s_path: lexer.filenames) { 99 | json src_info = { 100 | {"id", id}, 101 | {"name", getFileName(s_path)} 102 | }; 103 | string dir_path = getDirName(s_path); 104 | if (dir_path != "") { 105 | src_info["dir"] = dir_path; 106 | } 107 | files.push_back(src_info); 108 | } 109 | ast["files"] = files; 110 | 111 | (*jout) << std::setw(indent) << ast << endl; 112 | 113 | } else { 114 | string msg(PlnAstMessage::getErr(E_CouldnotOpenFile, fname)); 115 | cerr << "pat: error: " << msg << endl; 116 | return 1; 117 | } 118 | 119 | return 0; 120 | } 121 | 122 | string getDirName(string fpath) 123 | { 124 | int path_i = fpath.find_last_of("/\\")+1; 125 | return fpath.substr(0, path_i); 126 | } 127 | 128 | string getFileName(string& fpath) 129 | { 130 | int path_i = fpath.find_last_of("/\\")+1; 131 | return fpath.substr(path_i, fpath.length()); 132 | } 133 | --------------------------------------------------------------------------------