diff --git a/src/TODO b/src/TODO index 5fe1c8d548d77c074cc1be504e313b1cdca0247d..84b14cba049d1340decd4c763f95028c3154ce63 100644 --- a/src/TODO +++ b/src/TODO @@ -173,21 +173,6 @@ sont-ils sens * le merge -* Recursion statique - -la recursion statique ne marche pas ("with (n=1)" pas pris en compte) - -../lus2lic should_work/Pascal/consensus.lus -../lus2lic should_work/Pascal/t2.lus -../lus2lic should_work/Pascal/t0.lus - -node consensus<<const n : int>>(T: bool^n) returns (a: bool); -let - a = with (n = 1) - then T[0] - else T[0] and consensus << n-1 >> (T[1..n-1]); -tel - * dependance checking ex : a=b; diff --git a/src/compile.ml b/src/compile.ml index c1833122ffa0372b5e073b6a234592260aed0dfe..078147d771c7cbd4385f1dd9267cc762b5171574 100644 --- a/src/compile.ml +++ b/src/compile.ml @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 30/05/2008 (at 17:14) by Erwan Jahier> *) +(** Time-stamp: <modified the 01/07/2008 (at 14:55) by Erwan Jahier> *) open Lxm @@ -40,7 +40,7 @@ let (doit : SyntaxTree.pack_or_model list -> Ident.idref option -> unit) = in Verbose.printf "-- MAIN NODE: \"%s\"\n" - (CompiledDataDump.string_of_node_key main_node_key); + (CompiledDataDump.string_of_node_key_rec main_node_key); if !Global.compile_all_items then LazyCompiler.compile_all lzcomp diff --git a/src/compiledData.ml b/src/compiledData.ml index 4d6a48251d624a5fd069e9c003c29a438c880e6c..02d77682046d8b91dcf8cb54ec9d9fa6db3bcc83 100644 --- a/src/compiledData.ml +++ b/src/compiledData.ml @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 30/06/2008 (at 15:56) by Erwan Jahier> *) +(** Time-stamp: <modified the 01/07/2008 (at 14:11) by Erwan Jahier> *) (** @@ -186,7 +186,7 @@ and by_pos_op_eff = | WHEN_eff of var_info_eff | WHENOT_eff of var_info_eff | TUPLE_eff - | WITH_eff + | WITH_eff of val_exp_eff | CONCAT_eff | HAT_eff of int * val_exp_eff diff --git a/src/compiledDataDump.ml b/src/compiledDataDump.ml index eabe139bacfcbc33cb9bba5bd4f6828222cbb239..b0b20a0974d3829cf7d313fe0912ed2a530d5da5 100644 --- a/src/compiledDataDump.ml +++ b/src/compiledDataDump.ml @@ -85,19 +85,37 @@ and string_of_type_eff_list = function -and string_of_node_key (nkey: node_key) = +(* for printing recursive node *) +and string_of_node_key_rec (nkey: node_key) = + match nkey with + | (ik, []) -> long ik + | (ik, salst) -> + let astrings = List.map static_arg2string_rec salst in + sprintf "%s_%s" (long ik) (String.concat "_" astrings) + +(* for printing iterators *) +and string_of_node_key_iter (nkey: node_key) = match nkey with | (ik, []) -> long ik | (ik, salst) -> let astrings = List.map static_arg2string salst in sprintf "%s<<%s>>" (long ik) (String.concat ", " astrings) +(* for printing recursive node *) +and static_arg2string_rec (sa : static_arg_eff) = + match sa with + | ConstStaticArgEff (id, ceff) -> sprintf "%s" (string_of_const_eff ceff) + | TypeStaticArgEff (id, teff) -> sprintf "%s" (string_of_type_eff teff) + | NodeStaticArgEff (id, opeff) -> + sprintf "%s" (string_of_node_key_rec opeff.node_key_eff) + +(* for printing iterators *) and static_arg2string (sa : static_arg_eff) = match sa with | ConstStaticArgEff (id, ceff) -> sprintf "const %s" (string_of_const_eff ceff) | TypeStaticArgEff (id, teff) -> sprintf "type %s" (string_of_type_eff teff) | NodeStaticArgEff (id, opeff) -> - sprintf "node %s" (string_of_node_key opeff.node_key_eff) + sprintf "node %s" (string_of_node_key_iter opeff.node_key_eff) and (string_of_var_info_eff: var_info_eff -> string) = fun x -> @@ -167,7 +185,12 @@ and (string_of_by_pos_op_eff : by_pos_op_eff -> val_exp_eff list -> string) = ^ ">>") ^ (tuple vel)) | CALL_eff nee, _ -> ( - string_of_node_key nee.it.node_key_eff) ^ (tuple vel) + if nee.it.def_eff = ExternEff then + ((string_of_node_key_iter nee.it.node_key_eff) ^ (tuple vel)) + else + (* recursive node cannot be extern *) + ((string_of_node_key_rec nee.it.node_key_eff) ^ (tuple vel)) + ) | IDENT_eff idref, _ -> Ident.string_of_idref idref | PRE_eff, _ -> "pre" ^ (tuple vel) | ARROW_eff, [ve1; ve2] -> @@ -180,7 +203,7 @@ and (string_of_by_pos_op_eff : by_pos_op_eff -> val_exp_eff list -> string) = (string_of_val_exp_eff ve1) ^ " when not " ^ (string_of_val_exp_eff ve2) | CURRENT_eff,_ -> "current " ^ (tuple vel) | TUPLE_eff,_ -> (tuple vel) - | WITH_eff,_ -> "with " ^ (tuple vel) + | WITH_eff(ve),_ -> (string_of_val_exp_eff ve) | CONCAT_eff, [ve1; ve2] -> (string_of_val_exp_eff ve1) ^ " | " ^ (string_of_val_exp_eff ve2) | HAT_eff (i, ve), _ -> (string_of_val_exp_eff ve) ^ "^" ^ (string_of_int i) @@ -270,7 +293,7 @@ and (profile_of_node_exp_eff: node_exp_eff -> string) = wrap_long_profile ((if neff.def_eff = ExternEff then "extern " else "") ^ (if neff.has_mem_eff then "node " else "function ") ^ - (string_of_node_key neff.node_key_eff) ^ + (string_of_node_key_rec neff.node_key_eff) ^ "(" ^ (string_of_type_decl_list neff.inlist_eff "; ") ^ ") returns (" ^ (string_of_type_decl_list neff.outlist_eff "; ") ^ ");\n") @@ -320,7 +343,7 @@ and (node_of_node_exp_eff: node_exp_eff -> string) = "let\n " ^ (String.concat "\n " (string_of_node_def neff.def_eff)) ^ "\ntel\n-- end of node " ^ - (string_of_node_key neff.node_key_eff) ^ "\n" + (string_of_node_key_rec neff.node_key_eff) ^ "\n" ) ) @@ -354,7 +377,7 @@ and string_of_clock_list cl = Formatage standard des erreurs de compil ----------------------------------------------------------------------*) let node_error_string nkey = ( - Printf.sprintf "While checking %s" (string_of_node_key nkey) + Printf.sprintf "While checking %s" (string_of_node_key_iter nkey) ) (*--------------------------------------------------------------------- diff --git a/src/evalClock.ml b/src/evalClock.ml index 7817c83f307c8289f010fb356475ee6e45e989bd..ce103743f028dffe8d97389ceee7166c8267affe 100644 --- a/src/evalClock.ml +++ b/src/evalClock.ml @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 30/06/2008 (at 16:18) by Erwan Jahier> *) +(** Time-stamp: <modified the 01/07/2008 (at 14:15) by Erwan Jahier> *) open Predef @@ -308,7 +308,6 @@ and (eval_by_pos_clock : id_solver -> by_pos_op_eff -> Lxm.t -> val_exp_eff list | TUPLE_eff | ARROW_eff | FBY_eff - | WITH_eff | CONCAT_eff | ARRAY_eff -> ( (* Check that all args are of the same (unifiable) clocks. @@ -327,6 +326,9 @@ and (eval_by_pos_clock : id_solver -> by_pos_op_eff -> Lxm.t -> val_exp_eff list in clk_list, s ) + | WITH_eff(ve) -> f id_solver s ve + + and (eval_by_name_clock : id_solver -> by_name_op_eff -> Lxm.t -> (Ident.t Lxm.srcflagged * val_exp_eff) list -> subst -> diff --git a/src/evalConst.ml b/src/evalConst.ml index 9c2e9702c190607b2695762b6a061da0c08ba5b2..1d13816978f78668ea6f9d857949da9302722257 100644 --- a/src/evalConst.ml +++ b/src/evalConst.ml @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 09/06/2008 (at 10:03) by Erwan Jahier> *) +(** Time-stamp: <modified the 01/07/2008 (at 14:00) by Erwan Jahier> *) open Printf @@ -205,18 +205,11 @@ let rec f | x -> [ x ] ) (* opérateur lazzy *) - | WITH_n -> ( - match args with - [a0;a1;a2] -> ( - match (rec_eval_const a0) with - [ Bool_const_eff true] -> rec_eval_const a1 - | [ Bool_const_eff false] -> rec_eval_const a2 - | x -> type_error_const x "bool" - ) - | _ -> raise (EvalConst_error( - sprintf - "\n*** arity error: 3 expected instead of %d" - (List.length args))) + | WITH_n(a0,a1,a2) -> ( + match (rec_eval_const a0) with + [ Bool_const_eff true] -> rec_eval_const a1 + | [ Bool_const_eff false] -> rec_eval_const a2 + | x -> type_error_const x "bool" ) (* mettre à plat la liste des args *) | TUPLE_n -> ( List.flatten (List.map rec_eval_const args)) diff --git a/src/evalType.ml b/src/evalType.ml index 204c8d20addbc7dee7a658f0e246b995213939fb..6d03e877993fa66b3d9f13ba9d98810a06d31c5d 100644 --- a/src/evalType.ml +++ b/src/evalType.ml @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 30/06/2008 (at 15:57) by Erwan Jahier> *) +(** Time-stamp: <modified the 01/07/2008 (at 14:14) by Erwan Jahier> *) open Predef @@ -54,21 +54,8 @@ and (eval_by_pos_type : try [type_of_const_eff (id_solver.id2const id lxm)] with _ -> [(id_solver.id2var id lxm).var_type_eff] ) - | WITH_eff -> ( - match args with - [a0;a1;a2] -> ( - match (f id_solver a0) with - | [Bool_type_eff] -> - let teff1 = f id_solver a1 - and teff2 = f id_solver a2 in - if teff1 = teff2 then teff1 else - type_error [] "type mismatch in with statements" - | x -> type_error x "bool" - ) - | _ -> - raise (EvalType_error(sprintf "arity error: 3 expected instead of %d" - (List.length args))) - ) + | WITH_eff(ve) -> f id_solver ve + | TUPLE_eff -> List.flatten (List.map (f id_solver) args) | CONCAT_eff -> ( diff --git a/src/getEff.ml b/src/getEff.ml index 508425f1713763c86a1968205ea18bfa330a310d..722e5d145b92d801b5e7b27b86995e9ac4cf5f78 100644 --- a/src/getEff.ml +++ b/src/getEff.ml @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 30/06/2008 (at 16:15) by Erwan Jahier> *) +(** Time-stamp: <modified the 01/07/2008 (at 14:51) by Erwan Jahier> *) open Lxm @@ -150,7 +150,7 @@ and (check_static_arg : CompiledData.id_solver -> | StaticArgNode( (MERGE_n _|ARRAY_SLICE_n _|ARRAY_ACCES_n _|STRUCT_ACCESS_n _|IDENT_n _ - |ARRAY_n|HAT_n|CONCAT_n|WITH_n|TUPLE_n|WHEN_n|CURRENT_n|FBY_n + |ARRAY_n|HAT_n|CONCAT_n|WITH_n(_)|TUPLE_n|WHEN_n|CURRENT_n|FBY_n |ARROW_n|PRE_n)), _ -> assert false | StaticArgType _, StaticParamNode(id,_,_,_) @@ -235,11 +235,8 @@ and (translate_val_exp : id_solver -> val_exp -> val_exp_eff) = | CallByPos(by_pos_op, Oper vel) -> let vel_eff = List.map (translate_val_exp id_solver) vel in - CallByPosEff( - flagit - (translate_by_pos_op id_solver by_pos_op.it by_pos_op.src vel) - by_pos_op.src, - OperEff vel_eff) + let by_pos_op_eff = translate_by_pos_op id_solver by_pos_op vel in + CallByPosEff(flagit by_pos_op_eff by_pos_op.src, OperEff vel_eff) and translate_by_name_op = function @@ -307,9 +304,9 @@ and (translate_iteror: id_solver -> by_pos_op -> Lxm.t -> by_pos_op_eff) = | _ -> assert false -and (translate_by_pos_op : id_solver -> by_pos_op -> Lxm.t -> val_exp list -> +and (translate_by_pos_op : id_solver -> by_pos_op srcflagged -> val_exp list -> by_pos_op_eff) = - fun id_solver by_pos_op lxm args -> + fun id_solver {it=by_pos_op;src=lxm} args -> match by_pos_op with (* put that in another module ? yes, see above.*) | Predef(Map, _) @@ -333,7 +330,12 @@ and (translate_by_pos_op : id_solver -> by_pos_op -> Lxm.t -> val_exp list -> | CONCAT_n -> CONCAT_eff | TUPLE_n -> TUPLE_eff | ARRAY_n -> ARRAY_eff - | WITH_n -> WITH_eff + | WITH_n(c,e1,e2) -> + let c_eff = EvalConst.f id_solver c in + if c_eff = [ Bool_const_eff true ] then + WITH_eff (translate_val_exp id_solver e1) + else + WITH_eff (translate_val_exp id_solver e2) | STRUCT_ACCESS_n id -> STRUCT_ACCESS_eff id | WHEN_n -> diff --git a/src/lazyCompiler.ml b/src/lazyCompiler.ml index a136bde22fcd84809bc5d309ab758be626e4e548..f1382a7c55655dd258dd71b983a49c3d5969b1a8 100644 --- a/src/lazyCompiler.ml +++ b/src/lazyCompiler.ml @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 26/06/2008 (at 16:48) by Erwan Jahier> *) +(** Time-stamp: <modified the 01/07/2008 (at 14:01) by Erwan Jahier> *) open Lxm @@ -724,7 +724,7 @@ and (node_check_do: t -> CompiledData.node_key -> Lxm.t -> SymbolTab.t -> | CALL_n(node_alias) -> GetEff.node node_id_solver node_alias | (MERGE_n _|ARRAY_SLICE_n _|ARRAY_ACCES_n _|STRUCT_ACCESS_n _ - |IDENT_n _|ARRAY_n|HAT_n|CONCAT_n|WITH_n|TUPLE_n|WHEN_n + |IDENT_n _|ARRAY_n|HAT_n|CONCAT_n|WITH_n(_)|TUPLE_n|WHEN_n |CURRENT_n|FBY_n|ARROW_n|PRE_n) -> raise (Compile_error (lxm, "can not alias this operator, sorry")) diff --git a/src/parser.mly b/src/parser.mly index b195436cca30bcf0512cfea4f2184782c7126dca..93ad391ead9dfd20a2cbd5c731aabeccfc5c3b4c 100644 --- a/src/parser.mly +++ b/src/parser.mly @@ -775,7 +775,7 @@ sxExpression: | TK_IF sxExpression TK_THEN sxExpression TK_ELSE sxExpression { ternexp_predef $1 IF_n $2 $4 $6 } | TK_WITH sxExpression TK_THEN sxExpression TK_ELSE sxExpression - { ternexp $1 WITH_n $2 $4 $6 } + { CallByPos( {src = $1 ; it = WITH_n($2, $4, $6) }, Oper [] ) } /* n-aires */ /* WARNING ! il faut remettre la liste à l'endroit */ | TK_DIESE TK_OPEN_PAR sxExpressionList TK_CLOSE_PAR diff --git a/src/syntaxTreeCore.ml b/src/syntaxTreeCore.ml index d5bd7a13045d87d2d2d57dedfea8ae225b9ca175..cf1afc6dca97d724686b0f05f50525f3ffc2eb71 100644 --- a/src/syntaxTreeCore.ml +++ b/src/syntaxTreeCore.ml @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 10/06/2008 (at 10:49) by Erwan Jahier> *) +(** Time-stamp: <modified the 01/07/2008 (at 13:59) by Erwan Jahier> *) (** (Raw) Abstract syntax tree of source programs. *) @@ -97,7 +97,7 @@ and by_pos_op = | WHEN_n | TUPLE_n - | WITH_n + | WITH_n of val_exp * val_exp * val_exp | CONCAT_n | HAT_n diff --git a/src/syntaxTreeDump.ml b/src/syntaxTreeDump.ml index 09207f6ce71349415734c21da1402c1017576b4e..376fba6ce7f321995586bfb9a5592539ae6088d2 100644 --- a/src/syntaxTreeDump.ml +++ b/src/syntaxTreeDump.ml @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 05/06/2008 (at 11:10) by Erwan Jahier> *) +(** Time-stamp: <modified the 01/07/2008 (at 14:02) by Erwan Jahier> *) open Lxm @@ -33,7 +33,7 @@ let (op2string : SyntaxTreeCore.by_pos_op -> string) = | (CONCAT_n ) -> "|" | (IDENT_n idref) -> Ident.string_of_idref idref | (FBY_n ) -> "fby" - | (WITH_n ) -> "with" + | (WITH_n(_,_,_)) -> "with" | (TUPLE_n ) -> assert false | (CALL_n _ ) -> assert false | (ARRAY_n ) -> assert false @@ -417,7 +417,7 @@ and dump_by_pos_exp (os: Format.formatter) (oper: by_pos_op) (pars: operands) = | (HAT_n, Oper [p0;p1]) -> dump_binary_exp os "^" p0 p1 | (CONCAT_n, Oper [p0;p1]) -> dump_binary_exp os "|" p0 p1 | (Predef (IF_n,_), Oper [p0;p1;p2]) -> dump_ternary_exp os "if" "then" "else" p0 p1 p2 - | (WITH_n, Oper [p0;p1;p2]) -> dump_ternary_exp os "with" "then" "else" p0 p1 p2 + | (WITH_n(_), Oper [p0;p1;p2]) -> dump_ternary_exp os "with" "then" "else" p0 p1 p2 | (Predef (NOR_n,_), Oper pl) -> dump_nary_exp os "nor" pl | (Predef (DIESE_n,_), Oper pl) -> dump_nary_exp os "#" pl | (TUPLE_n, Oper pl) -> dump_nary_exp os "" pl @@ -440,7 +440,7 @@ and dump_by_pos_exp (os: Format.formatter) (oper: by_pos_op) (pars: operands) = | (STRUCT_ACCESS_n _, _) -> assert false | (ARRAY_SLICE_n _, _) -> assert false | (ARRAY_ACCES_n _, _) -> assert false - | (WITH_n, _) -> assert false + | (WITH_n(_), _) -> assert false | (CONCAT_n, _) -> assert false | (HAT_n, _) -> assert false diff --git a/src/test/should_work/Pascal/consensus.lus b/src/test/should_work/Pascal/consensus.lus index f446c21f53004d5247a490c9437637689ae2751e..792cc7325c9aaf9990ff11bdb9e73375e1eec421 100644 --- a/src/test/should_work/Pascal/consensus.lus +++ b/src/test/should_work/Pascal/consensus.lus @@ -21,7 +21,7 @@ node consensus<<const n : int>>(T: bool^n) returns (a: bool); let a = with (n = 1) then T[0] - else T[0] and consensus << n-1 >> (T[1..n-1]); + else T[0] and consensus << n-1 >> (T[1 .. n-1]); tel (* diff --git a/src/test/test.res.exp b/src/test/test.res.exp index 88bfd631abb44a97cf06d7a7ba9f571a2c022d70..d623a9ef5c7aa53bea767b37b65d326cdc0da890 100644 --- a/src/test/test.res.exp +++ b/src/test/test.res.exp @@ -2803,10 +2803,71 @@ tel ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 --compile-all-items should_work/Pascal/consensus.lus Opening file /home/jahier/lus2lic/src/test/should_work/Pascal/consensus.lus -*** Error in file "should_work/Pascal/consensus.lus", line 24, col 40 to 42, token '1..': -*** -*** can't eval constant: array index 1 out of bounds 0..0 - +node consensus::consensus_1(T:bool^1) returns (a:bool); +let + a = T[0]; +tel +-- end of node consensus::consensus_1 +node consensus::consensus_2(T:bool^2) returns (a:bool); +let + a = (T[0] and consensus::consensus_1(T[1..1])); +tel +-- end of node consensus::consensus_2 +node consensus::consensus_3(T:bool^3) returns (a:bool); +let + a = (T[0] and consensus::consensus_2(T[1..2])); +tel +-- end of node consensus::consensus_3 +node consensus::consensus_4(T:bool^4) returns (a:bool); +let + a = (T[0] and consensus::consensus_3(T[1..3])); +tel +-- end of node consensus::consensus_4 +node consensus::main(T:bool^4) returns (c:bool); +let + c = consensus::consensus_4(T); +tel +-- end of node consensus::main +node consensus::consensus_5(T:bool^5) returns (a:bool); +let + a = (T[0] and consensus::consensus_4(T[1..4])); +tel +-- end of node consensus::consensus_5 +node consensus::consensus_6(T:bool^6) returns (a:bool); +let + a = (T[0] and consensus::consensus_5(T[1..5])); +tel +-- end of node consensus::consensus_6 +node consensus::consensus_7(T:bool^7) returns (a:bool); +let + a = (T[0] and consensus::consensus_6(T[1..6])); +tel +-- end of node consensus::consensus_7 +node consensus::consensus_8(T:bool^8) returns (a:bool); +let + a = (T[0] and consensus::consensus_7(T[1..7])); +tel +-- end of node consensus::consensus_8 +node consensus::consensus_9(T:bool^9) returns (a:bool); +let + a = (T[0] and consensus::consensus_8(T[1..8])); +tel +-- end of node consensus::consensus_9 +node consensus::consensus_10(T:bool^10) returns (a:bool); +let + a = (T[0] and consensus::consensus_9(T[1..9])); +tel +-- end of node consensus::consensus_10 +node consensus::main2(T:bool^10) returns (a:bool); +let + a = consensus::consensus_10(T); +tel +-- end of node consensus::main2 +node consensus::c8(T:bool^8) returns (a:bool); +let + a = consensus::consensus_8(T); +tel +-- end of node consensus::c8 ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 --compile-all-items should_work/Pascal/fby.lus @@ -3630,10 +3691,42 @@ tel ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 --compile-all-items should_work/Pascal/t0.lus Opening file /home/jahier/lus2lic/src/test/should_work/Pascal/t0.lus -*** Error in file "should_work/Pascal/t0.lus", line 13, col 37 to 39, token '1..': -*** -*** can't eval constant: array index 1 out of bounds 0..0 - +node t0::min_n_1(T:int^1) returns (mn:int); +let + mn = T[0]; +tel +-- end of node t0::min_n_1 +node t0::min(x:int; y:int) returns (mn:int); +let + mn = if ((x <= y)) then (x) else (y); +tel +-- end of node t0::min +node t0::min_n_2(T:int^2) returns (mn:int); +let + mn = t0::min(T[0], t0::min_n_1(T[1..1])); +tel +-- end of node t0::min_n_2 +node t0::min_n_3(T:int^3) returns (mn:int); +let + mn = t0::min(T[0], t0::min_n_2(T[1..2])); +tel +-- end of node t0::min_n_3 +node t0::min_n_4(T:int^4) returns (mn:int); +let + mn = t0::min(T[0], t0::min_n_3(T[1..3])); +tel +-- end of node t0::min_n_4 +node t0::min_4(T:int^4) returns (mn:int); +let + mn = t0::min_n_4(T); +tel +-- end of node t0::min_4 +node t0::t0(T:int^4) returns (mn:int); +let + mn = t0::min_4(T); +tel +-- end of node t0::t0 +extern function t0::max(x:int; y:int) returns (mx:int); ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 --compile-all-items should_work/Pascal/t1.lus